我遇到了如下情况,我不确定struct的std::string元素是否泄漏内存,或者这是否可以。当调用free(v)
时,这两个std::字符串分配的内存是否被删除?
struct MyData
{
std::string s1;
std::string s2;
};
void* v = malloc(sizeof(MyData));
…
MyData* d = static_cast<MyData*>(v);
d->s1 = "asdf";
d->s2 = "1234";
…
free(v);
是否泄漏?
我使用空指针是因为我有另一个高级结构体,它由枚举和空指针组成。根据枚举变量的值,void*将指向不同的数据结构。
的例子:
enum-field has EnumValue01 => void-pointer将指向malloc'd MyData01结构
enum-field has EnumValue02 => void-pointer将指向malloc'd MyData02 struct
你不应该在c++程序中使用malloc()
和free()
;它们不支持构造函数/析构函数。
使用new
和delete
操作符
这是未定义的行为- malloc()
在未初始化时分配的内存,因此将其用作包含string
对象的结构体可以导致任何结果;我估计会撞车。由于在调用free()
之前没有人调用析构函数,因此string
对象不会被销毁,并且它们的缓冲区几乎肯定会泄漏。
确实有泄漏。free不调用MyData析构函数(毕竟它是一个C函数,不知道任何c++的东西)。或者你应该使用new/delete而不是malloc/free:
<>之前
MyData* d = new MyData;
d->s1 = "asdf";
d->s2 = "1234";
delete d;
之前或者自己调用析构函数:
<>之前
void* v = malloc(sizeof(MyData));
MyData* d = new (v) MyData; // use placement new instead of static_cast
d->s1 = "asdf";
d->s2 = "1234";
...
d->~MyData();
free(v);
之前正如sharptooth指出的那样,你不能直接使用malloc分配的内存作为MyData结构体而不进行初始化,所以你也必须自己做。要使用已经分配的内存初始化MyData,您需要使用placement new(参见上面的代码)。
可以,因为没有调用构造函数和析构函数。使用new
和delete
即使您设法正确地初始化s1和s2,简单地执行free(d)也不会回收为s1和s2动态分配的任何内存。您应该通过new创建*d,通过delete创建destroy,这将确保正确地销毁s1和s2(以及初始化)。
是的,您可能正在泄漏,并且您的字符串也没有正确构造。程序的行为是未定义的,这意味着一切都将出错。
最接近你正在做的事情的有效方法是放置new
。不过,最好还是有一些通用的基类和适当的c++多态性。
如果可能的类型不相关,则可以使用Boost。Any or Boost.Variant.