首页 > 解决方案 > Webassemly 内存管理和指针

问题描述

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

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 那么这个例子仍然有效!!!这意味着我可以像这样在 java 脚本中使用字符串(在购买的场景中,即删除和不删除):

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

如果在下一个函数调用期间调用“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;

然后我得到一些随机垃圾而不是字符串。起初我认为这是因为向量是“自动”清理的,因为它在堆栈上“活动”,与堆(免费存储)上“活动”的“char_array”相反。但情况似乎并非如此。我在这里缺少什么。

在被 javaScript 消耗后,如何手动释放使用 new 运算符在此处动态分配的内存。

Module._free(ptr); 

似乎没有工作。我怎样才能确保“char_array”对象被清理并且它的内存在被 JavaScript 消耗后被释放?

标签: c++memory-leakswebassembly

解决方案


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

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

然后我得到一些随机垃圾而不是字符串。

JavaScript 不理解vector类型。


推荐阅读