2

I have this (simplified) C++ class:

class node{
public:
    int num;
    list<int> iplist;   
};

Then I dynamically allocate memory for it:

node* node1 = (node*) malloc( sizeof(node) );

It's OK to use node1->num, it's totally fine. However, (node1->iplist).push_back(10)will cause segementation fault. I changed it back to:

node* node1 = new node;

It works fine again including (node1->iplist).push_back(10). I've Google'd for the answer, realizing maybe this is because malloc() doesn't initialize the element. But, I'm still confused on how to initialize a <list> element when using malloc().

jxh
  • 69,070
  • 8
  • 110
  • 193
Michael
  • 201
  • 1
  • 6
  • 16
  • `malloc` doesn't run constructors. Your program exhibits undefined behavior, by way of using a block of uninitialized memory as if it were a valid, fully constructed `node` instance. Why exactly do you want to use `malloc` in the first place? – Igor Tandetnik Oct 05 '14 at 03:32
  • 4
    Don't use `malloc` in C++ code. – n. m. could be an AI Oct 05 '14 at 03:32
  • 1
    *"But I'm still confused that how to initialize a element if I used malloc"* You shouldn't do that, that's essentially what `new` is for. Modern C++ even bans the use of `new` in favour of `make_unique` and `make_shared`. If you have to separate memory allocation from initialization, you must use placement-new to call the constructors manually: `node* node1 = static_cast(malloc(sizeof(node))); new(static_cast(node1)) node();` (include ``). – dyp Oct 05 '14 at 03:34
  • 2
    On of the *many* duplicates on this question : ["Accessing member of a C++ object allocated with malloc?"](http://stackoverflow.com/questions/8774232/accessing-member-of-a-c-object-allocated-with-malloc) – WhozCraig Oct 05 '14 at 03:34
  • @IgorTandetnik Because I use C more than C++ so I just want to try it in C++ and then I run into this question. – Michael Oct 05 '14 at 03:43
  • @WhozCraig Maybe I should delete this question? – Michael Oct 05 '14 at 03:44

2 Answers2

3

If you want to use malloc() to allocate your object, the most reliable way is to overload the new operator for your object.

class node{
public:
    int num;
    std::list<int> iplist;

    void * operator new (size_t sz) { return malloc(sz); }
    void operator delete (void *p) { free(p); }
    void * operator new[] (size_t sz) { return malloc(sz); }
    void operator delete[] (void *p) { free(p); }
};

With these overloads, using new or new[] will result in a call to malloc() to get the memory for the dynamic allocation request. A call to delete and delete[] will use free() to deallocate the memory.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • The reason this answer is more reliable than using placement `new` is that placement `new` requires you to explicitly call the destructor of the object before calling `free()`. This answer also still allows your object to be correctly managed by a smart pointer without requiring you to define a custom deleter. – jxh Oct 05 '14 at 04:07
2

If you want to use malloc for c++ objects, you have to use "placement new":

void *p = malloc( sizeof(node) );
node* node1 = new (p) node;
node1->iplist.push_back(10);
fghj
  • 8,898
  • 4
  • 28
  • 56