Webassembly 内存管理和指针

Webassemly memory management and pointers

我使用 webassembly 是为了使用标准库进行一些计算。在 webassembly 中我们只能传递 32 位整数和 64 位整数。这意味着我们也可以将指针传递给数组。这就是我们能够 return 字符串作为字符数组的方式,即 example

char* EMSCRIPTEN_KEEPALIVE returnStringCharacterArray()
{
  string stringToReturn = "I am learning web assembly";

   char* char_array = new char [stringToReturn.length()+1];
   strcpy (char_array, stringToReturn.c_str());

   char* arrayPtr = &char_array[0];
   // delete [] char_array;
   return arrayPtr;

}

注意该函数中的运算符 "new"。并注意那里从未调用过“delete [] char_array;”。这是否意味着如果我忘记在这里调用 delete 就会发生内存泄漏?我注意到这里有一件非常奇怪的事情。如果我在数组上调用 delete 那么这个例子仍然有效!!!这意味着我可以像这样在 java 脚本中使用字符串(在购买的场景中,即删除和不删除):

 var ptr = Module._returnStringCharacterArray();
 var ptr = new Uint8Array(Module.HEAPU8.buffer, ptr, length);
 var theStringObj = new TextDecoder('utf8').decode(ptr);
 console.log(newstring)

在下一个函数调用期间,如果调用 delete 函数,"char_array" 会发生什么?为什么即使调用了“delete [] char_array;”我仍然能够使用字符串?

我问这个的原因是因为我对向量的情况非常相似,即但是我没有指向字符的指针,而是指向 uint8_t 即:

const vector<uint8_t>&  someString;

当我尝试发送指针时,指向向量的第一个值返回到 java 脚本,即像这样

const uint8_t* wasmVectorArrayRecostructedPtr = &someString[0];
uint8_t* nonConstBufferReconstructed = const_cast<uint8_t*>(wasmVectorArrayRecostructedPtr);
char* charArrayPtrCasted = (char*) nonConstBufferReconstructed;

然后我得到一些随机垃圾而不是字符串。起初我以为这是因为 vector 被 "automatically" 清理了,因为它在堆栈上是 "living",与 "char_array" 相反,它在堆上是 "living"(免费商店)。但事实似乎并非如此。我在这里缺少什么。

javaScript 占用内存后,如何手动释放使用 new 运算符在这里动态分配的内存。

Module._free(ptr); 

似乎不​​起作用。 我如何确保 "char_array" 对象被清理并且它的内存在被 JavaScript 消耗后被释放?

WebAssembly 内存可以增长,但永远不会缩小。 delete 允许覆盖内存,但它仍保留供您的 WebAssembly 应用程序将来使用。

when i try to send the pointer, poiting to the first value of the vector back to java script

then i get some random garbage instead of the string.

JavaScript 不理解 vector 类型。

我认为你应该有另一个从 JavaScript 到 Wasm 的函数,通知 wasm 模块它可以释放支持字符串的内存,并在该函数内调用 delete 来释放原本会保留的线性内存。

类似于:

void EMSCRIPTEN_KEEPALIVE freeMemory(char* ptr)
{
     delete [] ptr;
}

否则你将在每次调用时不断实例化一堆字节,沿途泄漏内存。

这与 Wasm 内存只能增长这一事实无关。内存泄漏仍应注意。