4426

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

  • How to understand F-test based lmfit confidence intervals
  • Dynamically Creating PDF in Struts 2
  • Is there a way to use existing structs as enum variants?
  • Pseudo-WYSIWYG Emacs
  • change struct in method
  • C# equivalent to VB6 'Type'
  • Finding the start and stop indices in sequence in R
  • Is it possible to run only subsets of a Boost unit test module?
  • How can I group by time in SQL [duplicate]
  • Objects disappearing of ArrayList
  • iOS/Swift: in which function between viewDidLoad and viewWillAppear am I supposed to query a databas
  • Paypal Parallel Payment with Multiple Currencies
  • Pandas data types change when iterating over the major axis
  • Precompiled header and Visual Studio
  • What does “Load Playlist started” mean in Visual Studio?
  • How to retrieve code from .sikuli folder?
  • SQL: Query for a group that contains an exact set of users
  • php -> preg_replace -> remove space ONLY between quotes
  • R script - least squares solution to the following [duplicate]
  • time.Time: pointer or value
  • Read Values from .csv file and convert them to float arrays
  • javafx 3d performance large data set
  • Object and struct member access and address offset calculation
  • How to assign byte[] as a pointer in C#
  • Query to find the duplicates between the name and number in table
  • Android screen density dpi vs ppi
  • How would I use PHP exceptions to define a redirect?
  • How to extract text from Word files using C#?
  • How do you troubleshoot character encoding problems?
  • How to format a variable of double type
  • KeystoneJS: Relationships in Admin UI not updating
  • Hits per day in Google Big Query
  • embed rChart in Markdown
  • need help with bizarre java.net.HttpURLConnection behavior
  • Checking variable from a different class in C#
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • How can i traverse a binary tree from right to left in java?
  • How to Embed XSL into XML
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app