This is a minimal working example for the problem I am facing in my real code.
#include <iostream>
namespace Test1 {
static const std::string MSG1="Something really big message";
}
struct Person{
std::string name;
};
int main() {
auto p = (Person*)malloc(sizeof(Person));
p = new(p)Person();
p->name=Test1::MSG1;
std::cout << "name: "<< p->name << std::endl;
free(p);
std::cout << "done" << std::endl;
return 0;
}
When I compile it and run it via Valgrind, it gives me this error:
definitely lost: 31 bytes in 1 blocks
malloc
in the example above, as in my real code I use a C library in my C++ project, which uses this malloc
internally. So I can't get away from malloc
usage, as I don't do it explicitly anywhere in my code.std::string name
of Person
again and again in my code.The important pieces of your code line by line...
Allocate memory for one Person object:
auto p = (Person*)malloc(sizeof(Person));
Construct a Person object in that already allocated memory via calling its constructor:
p = new(p)Person();
Free the memory allocated via malloc:
free(p);
Calling the constructor via placement new
creates a std::string
. That string would be destroyed in the destructor but the destructor is never called. free
does not call destructors (just like malloc
does not call a constructor).
malloc
only allocates the memory. Placement new only constructs the object in already allocated memory. Hence you need to call the destructor before calling free
. This is the only case I am aware of where it is correct and necessary to explicitly call a destructor:
auto p = (Person*)malloc(sizeof(Person));
p = new(p)Person();
p->~Person();
free(p);