Possible memory leak with malloc, struct, std::string, and free

I've a situation like the following, and I'm not sure whether or not the std::string elements of the struct leak memory or if this is ok. Is the memory allocated by those two std::strings deleted when free(v) is called?

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);

Leak or not?

I'm using the void-pointer because I have another superior struct, which consists of an enum and a void-pointer. Depending on the value of the enum-variable, the void* will point to different data-structs.

Example:

enum-field has EnumValue01 => void-pointer will point to a malloc'd MyData01 struct

enum-field has EnumValue02 => void-pointer will point to a malloc'd MyData02 struct

Suggestions for different approaches are very appreciated, of course.

Answer1:

There is a leak indeed. free doesn't call MyData destructor (after all it's a C function which doesn't know anything about C++ stuff). Either you should use new/delete instead of malloc/free:


MyData* d = new MyData;
d->s1 = "asdf";
d->s2 = "1234";
delete d;

</pre>

or call destructor by yourself:


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);

</pre>

as sharptooth noted you can't directly use memory allocated by malloc as a MyData struct without initialization, so you have to do it by yourself as well. To initialize MyData using already allocated memory you need to use placement new (see in the code above).

Answer2:

You shouldn't be using malloc() and free() in a C++ program; they're not constructor/destructor-aware.

Use the new and delete operators.

Answer3:

That's undefined behavior - memory allocated by malloc() in uninitialized, so using it as a struct containing string objects can lead to anything; I'd expect crashing. Since no-one invokes the destructor before calling free(), string objects won't be destroyed and their buffers will almost definitely leak.

Answer4:

Yes, because the constructor and destructor are not called. Use new and delete.

Answer5:

Even if you manage to initialize s1 and s2 properly, simply doing free(d) won't reclaim any memory dynamically allocated for s1 and s2. You should really create *d through new and destroy through delete, which will ensure proper destruction of s1 and s2 (and initialization as well).

Answer6:

Yes, you are probably leaking, and your strings aren't properly constructed, either. The program's behaviour is undefined, meaning everything is going to go wrong.

The closest valid way to do what you're doing is placement new. Still, you'd be better off with some common base class and proper C++ polymorphism.

If the possible types are unrelated, you can use Boost.Any or Boost.Variant.

人吐槽 人点赞

Recommend

Comment

用户名: 密码:
验证码: 匿名发表

你可以使用这些语言

查看评论:Possible memory leak with malloc, struct, std::string, and free