当 C++ 类的内存已从 C malloc 中保留时,应该如何使用它?
我正在使用 C 库 (lua),我需要向它公开一个 C++ 类,在这种情况下,为了垃圾收集这些保留空间,lua 会保留内存。
一个更简单的类似场景如下:
#include <string>
class Clase{
private:
std::string valor;
public:
Clase(){}
Clase(const std::string & valor) : valor(valor){}
const std::string & get() const { return this->valor; }
void set(const std::string & valor){ this->valor = valor;}
~Clase(){}
};
typedef struct
{
Clase cls;
}Estructura;
int main(int argc, char ** argv)
{
Estructura * est = (Estructura *) malloc(sizeof(Estructura));
est->cls.set("Hola"); // First attempt
Clase myCls; // Second attempt
est->cls = myCls;
return 0;
}
我理解并检查过,使用 malloc 不会调用类构造函数;这是预期的,因此不能使用无效实例(类中的字符串)调用复制(赋值)运算符。我怀疑在复制 Class 实例中的字符串时,第二次尝试在同一点上失败了。
所以:
- 是否可以正确初始化一个由 malloc 保留其内存的类实例?
- 还有哪些其他注意事项?vtables?
- malloc 的 free 补充会导致内存泄漏吗? (我猜测由于不会调用 Clase 析构函数,因此不会正确释放字符串?[我假设字符串在实例本身之外保留内存])
在 Estructura 中使用 Clase 指针,效果很好,这是最好的解决方案吗?
作为奖励,当 lua 垃圾收集实例时删除实例的最佳方法是使用 __gc 元方法还是更好的方法?
最佳答案
使用 malloc
而不是 new
有点奇怪,但这是可能的。您需要使用新的展示位置:
void *memory = malloc(sizeof(Estructura));
Estructura *est = new(memory)Estructura;
当您完成对象后,您有责任自己调用析构函数:
est->~Estructura();
一切,例如 vtables,都会被正确初始化,因此无需担心。尴尬的一点是处理删除,因为您需要在通过 free
释放内存之前销毁对象。 delete
会自动为您执行此操作,但您需要自己执行此操作。
关于c++ - 使用 malloc() 初始化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30046987/