I wrote the following example program but it crashes with segfault. The problem seems to be with using malloc
and std::string
s in the structure.
#include <iostream>
#include <string>
#include <cstdlib>
struct example {
std::string data;
};
int main() {
example *ex = (example *)malloc(sizeof(*ex));
ex->data = "hello world";
std::cout << ex->data << std::endl;
}
I can't figure out how to make it work. Any ideas if it's even possible to use malloc()
and std::string
s?
Thanks, Boda Cydo.
Allocating memory with
malloc
doesn't call any constructors. Don't mix C-style allocation with C++ objects. They don't play well together. Instead, use thenew
operator to allocate objects in C++ code:This is smarter code and will call the
std::string::string()
constructor to initialize the string, which will fix the segfault you're seeing. And don't forget to delete it when you're done to free the memory and call the appropriate destructors:you should not use
because what sizeof(*ex) return is equal to size of long or size of int, which is due to you different compile surrounding. you can use code as follow:
For a
class
orstruct
such as yourexample
, the correct answer is usenew
notmalloc()
to allocate an instance. Onlyoperator new
knows how to call the constructors for thestruct
and its members. Your problem is caused by the string member not having ever been constructed.However, there are rare cases where it is important that a particular patch of memory act as if it holds an instance of a class. If you really have such a case, then there is a variation of
operator new
that permits the location of the object to be specified. This is called a "placement new" and must be used with great care.By using placement new, you are obligated to provide a region of memory of the correct size and alignment. Not providing the correct size or alignment will cause mysterious things to go wrong. Incorrect alignment is usually quicker to cause a problem but can also be mysterious.
Also, with a placement new, you are taking responsibility for calling the destructor by hand, and depending on the origin of the memory block, releasing it to its owner.
All in all, unless you already know you need a placement new, you almost certainly don't need it. It has legitimate uses, but there are obscure corners of frameworks and not everyday occurrences.
The problem is that
malloc
does not call the constructor ofexample
. Since astring
is usually represented as a pointer on the stack, this is set to zero, and you dereference a null pointer. You need to usenew
instead.You can't
malloc
a class with non-trivial constructor in C++. What you get frommalloc
is a block of raw memory, which does not contain a properly constructed object. Any attempts to use that memory as a "real" object will fail.Instead of
malloc
-ing object, usenew
Your original code can be forced to work with
malloc
as well, by using the following sequence of steps:malloc
raw memory first, construct the object in that raw memory second:The form of
new
used above is called "placement new". However, there's no need for all this trickery in your case.