问题
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.
回答1:
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;
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);
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).
回答2:
You shouldn't be using malloc()
and free()
in a C++ program; they're not constructor/destructor-aware.
Use the new
and delete
operators.
回答3:
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.
回答4:
Yes, because the constructor and destructor are not called. Use new
and delete
.
回答5:
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).
回答6:
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.
来源:https://stackoverflow.com/questions/7609981/possible-memory-leak-with-malloc-struct-stdstring-and-free