2

I'll try to make things clear.

Here is my struct:

struct scopeList{
       int id;
       list<int> internal_list;
};
typedef struct scopeList scopeList_T;

Here is the code that gives me the segmentation.

int main(){
    scopeList_T* t1 = (scopeList_T*) malloc(sizeof(scopeList_T));
    t1->id = 5; //works fine
    t1->internal_list.push_front(5); //segmentation fault
} 

Since I am allocating memory and accessing id is fine, why is does this give me a segmentation fault? Do I have to do something special to the list first?

Thanks!

slugster
  • 49,403
  • 14
  • 95
  • 145
Spap
  • 45
  • 1
  • 5

5 Answers5

5

Use new instead of malloc!

sopeList_T* t1 = new scopeList_T;

malloc doesn't run any constructors. When you need to release that struct, use delete rather than free - you can't free objects allocated with new (and free doesn't call destructors).

You don't need that typedef either, the struct declaration is enough.

struct scopeList {
    int id;
    list<int> internal_list;
};

int main()
{
    scopeList *t = new scopeList;
    ....
    delete t;
    ....
}
Mat
  • 202,337
  • 40
  • 393
  • 406
  • 1
    Also note, use `delete` instead of `free` – ildjarn Apr 02 '11 at 08:46
  • Thanks a lot, this really helped! Seems like I'm still thinking in C style! – Spap Apr 02 '11 at 08:46
  • 1
    @Spap: **actually**, using `new` and `delete` is also 'C style' (!). For C++ code style use a specialized container, smart pointer or simply make it a local variable. – Yakov Galka Apr 02 '11 at 10:31
  • @ybungalobill: exactly. If you still use something like `new` it must be the part of some type's constructor with matching `delete` in its destructor. – Serge Dundich Apr 02 '11 at 14:52
1

You don't initialize the list using a constructor, thus leaving invalid data at the position of internal_list.

mbx
  • 6,292
  • 6
  • 58
  • 91
1

Since malloc doesn't call constructor, you've to do either of these two ways:

  1. Use new to allocate the memory as well the construct the object:

    sopeList_T* t1 = new scopeList_T;//it allocates and then call the ctor!
    
    //use delete to deallocate the memory
    delete t1;
    
  2. Or use malloc to allocate the memory which you're already doing, and use placement new to construct the object:

    scopeList_T* t1 = (scopeList_T*) malloc(sizeof(scopeList_T)); //allocation
    t1 = new (t1) scopeList_T; //it calls the ctor 
    
    //use free to deallocate the memory
    t1->~scopeList_T(); //call the destructor explicitly - necessary!
    free(t1);
    
Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Allocating memory is not enough. You must also call the constructor.

The most common and recommended way of simple dynamic allocation in C++ is

scopeList_T* t1 = new scopeList_T;

is allocates memory and then calls constuctor.

After you're done with the stucture you have to delete the object like this

delete t1;

ADD:

If you really need to use other memory allocator (like malloc/free or something of your own design) then you have to allocate memory and call the placement new (it is like calling the constuctor explicitly). When you're done with the object you have to call the destructor explicitly and then deallocate memory. Important thing: memory allocated for the object must meet the alignment requirements for this object type.

Example:

// allocating memory
void* p = my_alloc( sizeof(scopeList_T) );

if( p == NULL )
{
// report allocation error and throw or return
}

// placement new operator
scopeList_T* t1 = new(p) scopeList_T; // t1 == p

// do some thing with the object
// .............................

// call destructor explicitly
t1->~scopeList_T();
// free memory
my_free(p); // or free(t1); that is the same
Serge Dundich
  • 4,221
  • 2
  • 21
  • 16
1

The right answers have been given above: You have allocated the memory of your struct but haven't run any constructors for the subobjects which are in uninitialized state. I have to insist: This is an absolute no-go. NEVER mix up calls to alloc & Co. with C++ code.

Paul Michalik
  • 4,331
  • 16
  • 18