Problem with calloc

Discussion in 'C++' started by ds, Feb 12, 2007.

  1. ds

    ds Guest

    Hello all,

    I have a problem with calloc I have never seen before. I am migrating
    some C code to C++ and at some part in the C code there is a calloc
    that creates an array of structures. Now in the C++ version, the
    structures are classes with virtual access functions. I am working on
    linux with g++ and it seems that the _vptr part of the class is null.
    Further use of these classes causes a segmentation fault. Of course if
    I use new everything is ok. I wonder if this is a limitation of the
    calloc implementation or if it is platform specific...

    Thanks a lot!!
     
    ds, Feb 12, 2007
    #1
    1. Advertising

  2. ds

    Rolf Magnus Guest

    ds wrote:

    > Hello all,
    >
    > I have a problem with calloc I have never seen before. I am migrating
    > some C code to C++ and at some part in the C code there is a calloc
    > that creates an array of structures. Now in the C++ version, the
    > structures are classes with virtual access functions. I am working on
    > linux with g++ and it seems that the _vptr part of the class is null.
    > Further use of these classes causes a segmentation fault. Of course if
    > I use new everything is ok. I wonder if this is a limitation of the
    > calloc implementation or if it is platform specific...


    calloc just fills all the allocated bytes with zero. This might be
    sufficient for POD types, but for non-POD classes, it isn't. The objects
    must be properly constructed, and calloc doesn't do this. That's why there
    is operator new.
     
    Rolf Magnus, Feb 12, 2007
    #2
    1. Advertising

  3. ds

    Jim Langston Guest

    "ds" <> wrote in message
    news:...
    > Hello all,
    >
    > I have a problem with calloc I have never seen before. I am migrating
    > some C code to C++ and at some part in the C code there is a calloc
    > that creates an array of structures. Now in the C++ version, the
    > structures are classes with virtual access functions. I am working on
    > linux with g++ and it seems that the _vptr part of the class is null.
    > Further use of these classes causes a segmentation fault. Of course if
    > I use new everything is ok. I wonder if this is a limitation of the
    > calloc implementation or if it is platform specific...
    >
    > Thanks a lot!!


    Yeah, pain in the neck isn't it? That is one big difference between C's
    structures and C++'s classes. A class that is not POD doesn't necessesarily
    want everything to be initialized to 0. This is something I ran across when
    working with some C code converting it to c++. The C code had something
    like:

    struct Foo
    {
    char String[100];
    int SomeInt;
    };

    Foo* Bar;

    Bar = malloc( sizeof Foo );
    // Now fill the memory with 0's

    Well, this was actually taking place in very differnet places (global
    variables, etc...). And I innocently tried to add a class to the structure.
    The same as:

    struct Foo
    {
    std::string Foo;
    int SomeInt;
    }

    And it took me a while to track down the zero filling of the memory and that
    the constructor was never being called.

    It's usually not a simple search and replace to fix this code, because some
    C code can get a little spagetti like, I spent days tracking down all the
    places this program was zero allocating memory.
     
    Jim Langston, Feb 12, 2007
    #3
  4. Jim Langston wrote:
    > "ds" <> wrote in message
    > news:...
    >> Hello all,
    >>
    >> I have a problem with calloc I have never seen before. I am migrating
    >> some C code to C++ and at some part in the C code there is a calloc
    >> that creates an array of structures. Now in the C++ version, the
    >> structures are classes with virtual access functions. I am working on
    >> linux with g++ and it seems that the _vptr part of the class is null.
    >> Further use of these classes causes a segmentation fault. Of course
    >> if I use new everything is ok. I wonder if this is a limitation of
    >> the calloc implementation or if it is platform specific...
    >>
    >> Thanks a lot!!

    >
    > Yeah, pain in the neck isn't it? That is one big difference between
    > C's structures and C++'s classes. A class that is not POD doesn't
    > necessesarily want everything to be initialized to 0. This is
    > something I ran across when working with some C code converting it to
    > c++. The C code had something like:
    >
    > struct Foo
    > {
    > char String[100];
    > int SomeInt;
    > };
    >
    > Foo* Bar;
    >
    > Bar = malloc( sizeof Foo );
    > // Now fill the memory with 0's
    >
    > Well, this was actually taking place in very differnet places (global
    > variables, etc...). And I innocently tried to add a class to the
    > structure. The same as:
    >
    > struct Foo
    > {
    > std::string Foo;
    > int SomeInt;
    > }
    >
    > And it took me a while to track down the zero filling of the memory
    > and that the constructor was never being called.


    Just to explain Jim's point: do NOT use 'malloc' or 'calloc' for non-
    POD types (especially when they can or do contain virtual functions)
    because that's going to interfere with (or simply forgo) proper
    construction of your objects.

    What's the alternative? 'new' and 'new[]'. When in Rome...

    > It's usually not a simple search and replace to fix this code,
    > because some C code can get a little spagetti like, I spent days
    > tracking down all the places this program was zero allocating memory.


    "Zero allocating" sounds wrong. You meant 'zero-initialising', right?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 12, 2007
    #4
  5. ds

    peter koch Guest

    On Feb 12, 4:10 pm, "Victor Bazarov" <> wrote:
    > Jim Langston wrote:
    > > "ds" <> wrote in message
    > >news:...
    > >> Hello all,

    >
    > >> I have a problem with calloc I have never seen before. I am migrating
    > >> some C code to C++ and at some part in the C code there is a calloc
    > >> that creates an array of structures. Now in the C++ version, the
    > >> structures are classes with virtual access functions. I am working on
    > >> linux with g++ and it seems that the _vptr part of the class is null.
    > >> Further use of these classes causes a segmentation fault. Of course
    > >> if I use new everything is ok. I wonder if this is a limitation of
    > >> the calloc implementation or if it is platform specific...

    >
    > >> Thanks a lot!!

    >
    > > Yeah, pain in the neck isn't it? That is one big difference between
    > > C's structures and C++'s classes. A class that is not POD doesn't
    > > necessesarily want everything to be initialized to 0. This is
    > > something I ran across when working with some C code converting it to
    > > c++. The C code had something like:

    >
    > > struct Foo
    > > {
    > > char String[100];
    > > int SomeInt;
    > > };

    >
    > > Foo* Bar;

    >
    > > Bar = malloc( sizeof Foo );
    > > // Now fill the memory with 0's

    >
    > > Well, this was actually taking place in very differnet places (global
    > > variables, etc...). And I innocently tried to add a class to the
    > > structure. The same as:

    >
    > > struct Foo
    > > {
    > > std::string Foo;
    > > int SomeInt;
    > > }

    >
    > > And it took me a while to track down the zero filling of the memory
    > > and that the constructor was never being called.

    >
    > Just to explain Jim's point: do NOT use 'malloc' or 'calloc' for non-
    > POD types (especially when they can or do contain virtual functions)
    > because that's going to interfere with (or simply forgo) proper
    > construction of your objects.
    >
    > What's the alternative? 'new' and 'new[]'. When in Rome...


    My advice would be to replace malloc and friends with new, std::vector
    and std::string. This should be the first step in a conversion, the
    second being to write constructors and destructors and ensure RAII is
    in use everywhere. There is no reason to use new[] unless you are in a
    very special situation.

    >
    > > It's usually not a simple search and replace to fix this code,
    > > because some C code can get a little spagetti like, I spent days
    > > tracking down all the places this program was zero allocating memory.

    >
    > "Zero allocating" sounds wrong. You meant 'zero-initialising', right?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask- Hide quoted text -
    >
    > - Show quoted text -
     
    peter koch, Feb 12, 2007
    #5
  6. ds

    Jim Langston Guest

    "Victor Bazarov" <> wrote in message
    news:eqq014$92i$...
    > Jim Langston wrote:
    >> "ds" <> wrote in message
    >> news:...
    >>> Hello all,
    >>>
    >>> I have a problem with calloc I have never seen before. I am migrating
    >>> some C code to C++ and at some part in the C code there is a calloc
    >>> that creates an array of structures. Now in the C++ version, the
    >>> structures are classes with virtual access functions. I am working on
    >>> linux with g++ and it seems that the _vptr part of the class is null.
    >>> Further use of these classes causes a segmentation fault. Of course
    >>> if I use new everything is ok. I wonder if this is a limitation of
    >>> the calloc implementation or if it is platform specific...
    >>>
    >>> Thanks a lot!!

    >>
    >> Yeah, pain in the neck isn't it? That is one big difference between
    >> C's structures and C++'s classes. A class that is not POD doesn't
    >> necessesarily want everything to be initialized to 0. This is
    >> something I ran across when working with some C code converting it to
    >> c++. The C code had something like:
    >>
    >> struct Foo
    >> {
    >> char String[100];
    >> int SomeInt;
    >> };
    >>
    >> Foo* Bar;
    >>
    >> Bar = malloc( sizeof Foo );
    >> // Now fill the memory with 0's
    >>
    >> Well, this was actually taking place in very differnet places (global
    >> variables, etc...). And I innocently tried to add a class to the
    >> structure. The same as:
    >>
    >> struct Foo
    >> {
    >> std::string Foo;
    >> int SomeInt;
    >> }
    >>
    >> And it took me a while to track down the zero filling of the memory
    >> and that the constructor was never being called.

    >
    > Just to explain Jim's point: do NOT use 'malloc' or 'calloc' for non-
    > POD types (especially when they can or do contain virtual functions)
    > because that's going to interfere with (or simply forgo) proper
    > construction of your objects.
    >
    > What's the alternative? 'new' and 'new[]'. When in Rome...
    >
    >> It's usually not a simple search and replace to fix this code,
    >> because some C code can get a little spagetti like, I spent days
    >> tracking down all the places this program was zero allocating memory.

    >
    > "Zero allocating" sounds wrong. You meant 'zero-initialising', right?


    Yeah, I guess I just made "zero allocating" up without even realizing it,
    meaning allocating memory then zero filling it.
     
    Jim Langston, Feb 12, 2007
    #6
  7. ds

    ds Guest

    Hello all

    and thanks for the answers!!! I really got unstuck, I was wondering
    why calloc wouldn't allocate memory the same way for an object just as
    new (since I already could observe the difference). Note, that without
    virtual methods, calloc works. However it is true that the object is
    not constructed appropriately as is the case with new. However, if I
    explicitly construct the elements using

    ::new ((void*)ptr) TYPE;

    where ptr is the pointer to the object and TYPE the type of the
    object, the object is properly constructed. I of course understand
    that this is not the correct way. However, since I plan to perform the
    migration iteratively, I would like for the moment to maintain the "C"
    styke memory management, check that the algorithm works, and change it
    alltogether to any prper C++ memory management scheme that we will
    decide on.

    Thanks for all the answers and help!!!
     
    ds, Feb 12, 2007
    #7
  8. ds wrote:
    > Hello all
    >
    > and thanks for the answers!!! I really got unstuck, I was wondering
    > why calloc wouldn't allocate memory the same way for an object just as
    > new (since I already could observe the difference). Note, that without
    > virtual methods, calloc works. However it is true that the object is
    > not constructed appropriately as is the case with new. However, if I
    > explicitly construct the elements using
    >
    >>> new ((void*)ptr) TYPE;


    No need to cast to void*.

    > where ptr is the pointer to the object and TYPE the type of the
    > object, the object is properly constructed. I of course understand
    > that this is not the correct way.


    Actually, it's fine. It's called "placement new", and it exists
    specifically for doing what you did, constructing in the memory you
    have acquired somehow, beforehand.

    Just don't 'delete' that pointer. Use the explicit destructor call
    and then deallocate your memory as you normally would:

    ptr->~TYPE();
    free(ptr);

    > However, since I plan to perform the
    > migration iteratively, I would like for the moment to maintain the "C"
    > styke memory management, check that the algorithm works, and change it
    > alltogether to any prper C++ memory management scheme that we will
    > decide on.


    Up to you.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 12, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrey Tarasevich
    Replies:
    0
    Views:
    476
    Andrey Tarasevich
    Sep 2, 2003
  2. Kevin Goodsell
    Replies:
    0
    Views:
    497
    Kevin Goodsell
    Sep 2, 2003
  3. luca
    Replies:
    5
    Views:
    27,041
    Default User
    Mar 2, 2004
  4. kdogksu

    calloc problem

    kdogksu, Apr 5, 2004, in forum: C Programming
    Replies:
    3
    Views:
    540
    Al Bowers
    Apr 5, 2004
  5. Calloc problem

    , Sep 29, 2005, in forum: C Programming
    Replies:
    2
    Views:
    363
    Randy Howard
    Sep 29, 2005
Loading...

Share This Page