pointers in structures?

Discussion in 'C Programming' started by N Yiannakoulias, Sep 30, 2003.

  1. Hello all,

    I am trying to initialize a pointer inside an evil global structure. The
    pointer neighbour_id is of different size for each of the 10 cells
    initialized in the function main:

    struct cells
    {
    int id;
    int x;
    int y;
    int number_neighbours;
    int *neighbour_id;
    };

    int main(void)
    {
    struct cells *the_cells;
    the_cells=malloc(sizeof(*the_cells)*10);
    /*check for memory availability...*/

    /*
    For each element of the structure, there are different number of
    neighbours (thus neighbour_id, a list of neighbour
    identifiers, is a different size for each element of the
    structure. How do I initialize this on a 'cell-by'cell' basis?
    is it something like:
    the_cells.neighbour_id=malloc(sizeof(??))*5) if I want to
    allocate space for 5 'values' in the pointer?
    */

    free(the_cells);
    /*I'll also want to free memory used by the pointers in
    the structure? Is that necessary?*/
    return 0;
    }

    Thanks for any guidance,

    N

    --
    -----------------------------------------------
    Conveniently located at lat 53 31'.01, lon 113 30'.26

    www.ualberta.ca/~nwy
     
    N Yiannakoulias, Sep 30, 2003
    #1
    1. Advertising

  2. N Yiannakoulias

    Martijn Guest

    N Yiannakoulias wrote:
    > Hello all,
    >
    > I am trying to initialize a pointer inside an evil global structure.
    > The pointer neighbour_id is of different size for each of the 10 cells
    > initialized in the function main:


    <nitpick>the pointer will most likely be of the same size, it will point to
    different size "memory blocks" :)</nitpick>

    > struct cells
    > {
    > int id;
    > int x;
    > int y;
    > int number_neighbours;
    > int *neighbour_id;
    > };
    >
    > int main(void)
    > {
    > struct cells *the_cells;
    > the_cells=malloc(sizeof(*the_cells)*10);
    > /*check for memory availability...*/
    >
    > /*
    > For each element of the structure, there are different number of
    > neighbours (thus neighbour_id, a list of neighbour
    > identifiers, is a different size for each element of the
    > structure. How do I initialize this on a 'cell-by'cell' basis?
    > is it something like:
    > the_cells.neighbour_id=malloc(sizeof(??))*5) if I want to
    > allocate space for 5 'values' in the pointer?
    > */


    That looks about right. The safest thing for the sizeof operator is to
    dereference the pointer, and take the size of that. For example (where n is
    the amount of neighbors):

    the_cells.neighbour_id = malloc(sizeof(*the_cells.neighbour_id));

    you could also just specify the type, altough this is not considered to be
    very flexible (because if the neighbour_id would point to a different type,
    you'd have to change this code as well):

    the_cells.neighbour_id = malloc(sizeof(int));

    >
    > free(the_cells);
    > /*I'll also want to free memory used by the pointers in
    > the structure? Is that necessary?*/


    Yip, it is, and make sure you do that _before_ you free the_cells, like so
    (declarations are omitted):

    for ( i = 0 ; i < cellcount ; ++i )
    {
    if ( the_cells.neighbour_id != NULL )
    free(the_cells.neighbour_id);
    }
    free(the_cells);

    Of course this requires the neighbour_id to be initialized to NULL if it's
    not being used and the_cells to point to something.

    > return 0;
    > }
    >
    > Thanks for any guidance,


    Hope this helps,

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Sep 30, 2003
    #2
    1. Advertising

  3. N Yiannakoulias

    Eric Sosman Guest

    Martijn wrote:
    >
    > That looks about right. The safest thing for the sizeof operator is to
    > dereference the pointer, and take the size of that. For example (where n is
    > the amount of neighbors):
    >
    > the_cells.neighbour_id = malloc(sizeof(*the_cells.neighbour_id));


    ITYM

    the_cells.neighbour_id = malloc(n * sizeof(*the_cells.neighbour_id));
    ^^^^

    --
     
    Eric Sosman, Sep 30, 2003
    #3
  4. N Yiannakoulias

    Al Bowers Guest

    N Yiannakoulias wrote:
    > Hello all,
    >
    > I am trying to initialize a pointer inside an evil global structure. The
    > pointer neighbour_id is of different size for each of the 10 cells
    > initialized in the function main:
    >
    > struct cells
    > {
    > int id;
    > int x;
    > int y;
    > int number_neighbours;
    > int *neighbour_id;
    > };
    >
    > int main(void)
    > {
    > struct cells *the_cells;
    > the_cells=malloc(sizeof(*the_cells)*10);
    > /*check for memory availability...*/



    You could jist declare an are of the structs.
    the_cells[10] = {0};
    But if you insist on dynamic allocation then use function calloc
    to allocate the array of struct cells.
    calloc allocates an array in memory with elements initialized to 0.
    This assures that all the elements member neighbour_id are null
    oointers. If for some reason you to not assign values to all
    the elements, you can still safely free neighbour_id since they
    are null pointers.

    >
    > /*
    > For each element of the structure, there are different number of
    > neighbours (thus neighbour_id, a list of neighbour
    > identifiers, is a different size for each element of the
    > structure. How do I initialize this on a 'cell-by'cell' basis?
    > is it something like:
    > the_cells.neighbour_id=malloc(sizeof(??))*5) if I want to
    > allocate space for 5 'values' in the pointer?
    > */


    .... malloc(sizeof(int) *5)
    >
    > free(the_cells);
    > /*I'll also want to free memory used by the pointers in
    > the structure? Is that necessary?*/


    Yes you will need to free all the neighbour_id pointers before you free
    the_cells.

    > return 0;
    > }


    #include <stdlib.h>
    #include <stdio.h>

    struct cells
    {
    int id;
    int x;
    int y;
    int number_neighbours;
    int *neighbour_id;
    };

    int main(void)
    {
    struct cells *the_cells;
    int i;
    the_cells=calloc(10,sizeof(*the_cells));
    if(the_cells == NULL) exit(EXIT_FAILURE);
    the_cells[0].number_neighbours = 5;
    the_cells[0].neighbour_id =
    malloc(sizeof(int)*the_cells[0].number_neighbours);
    if(the_cells[0].neighbour_id)
    {
    for(i = 0; i < the_cells[0].number_neighbours ;i++)
    {
    the_cells[0].neighbour_id = i*10;
    printf("the_cells[0].neighbour_id[%d] = %d\n",
    i, the_cells[0].neighbour_id);
    }
    }
    for(i = 0;i < 10;i ++)
    free(the_cells.neighbour_id);
    free(the_cells);
    return 0;
    }
     
    Al Bowers, Sep 30, 2003
    #4
  5. N Yiannakoulias

    Martijn Guest

    Eric Sosman wrote:
    > Martijn wrote:
    >>
    >> That looks about right. The safest thing for the sizeof operator is
    >> to dereference the pointer, and take the size of that. For example
    >> (where n is the amount of neighbors):
    >>
    >> the_cells.neighbour_id =

    malloc(sizeof(*the_cells.neighbour_id));
    >
    > ITYM
    >
    > the_cells.neighbour_id = malloc(n *

    sizeof(*the_cells.neighbour_id));
    > ^^^^


    oOps...

    Sorry about that...

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Oct 1, 2003
    #5
  6. On Tue, 30 Sep 2003 19:43:32 UTC, Al Bowers <>
    wrote:

    >
    >
    > N Yiannakoulias wrote:
    > > Hello all,
    > >
    > > I am trying to initialize a pointer inside an evil global structure. The
    > > pointer neighbour_id is of different size for each of the 10 cells
    > > initialized in the function main:
    > >
    > > struct cells
    > > {
    > > int id;
    > > int x;
    > > int y;
    > > int number_neighbours;
    > > int *neighbour_id;
    > > };
    > >
    > > int main(void)
    > > {
    > > struct cells *the_cells;
    > > the_cells=malloc(sizeof(*the_cells)*10);
    > > /*check for memory availability...*/

    >
    >
    > You could jist declare an are of the structs.
    > the_cells[10] = {0};
    > But if you insist on dynamic allocation then use function calloc
    > to allocate the array of struct cells.


    NO! calloc() is bad when you have to nullify anything else than char.
    An int or pointer is NOT always null when all bits are null. Whenever
    you have different data types to preset to some value (even null
    value) you should assign that type explicity when a stastic
    initialisation is impossible. OR make a static struct that can word as
    a memcompy to get a default initialisation.

    If a variable in a struct can have padding bits you can get undefined
    behavior if you tries to write 0 to the whole structure.

    Even if it seems that it works with your compiler - it would not work
    when you have to compile with another compiler, on another system or
    even with another version of your compiler.

    > calloc allocates an array in memory with elements initialized to 0.


    gives undefined behavior

    > This assures that all the elements member neighbour_id are null
    > oointers. If for some reason you to not assign values to all
    > the elements, you can still safely free neighbour_id since they
    > are null pointers.


    A NULL pointer can have some bits set! A pointer with all bits 0 is
    NOT guarateed to be a NULL pointer. Assign NULL ('\0', (pointer_type)
    0 or simply 0, 0x00, 000) is NOT identical with settings all bytes of
    sizeof(pointer) to 0. Whenever you assigns the pointer to 0 (NULL, \0
    the compiler will assign it a NULL ponter constant. overwriting the
    single bytes as calloc() does can't do that, so any access to that
    pointer can fail.

    Assigning any basetype (int, long, float..... byte by byte with 0
    bytes doesn't even mean assigning that variable a 0 - it mans only
    assigning some bytes with 0. Overwrite some padding bits can result in
    something unwanted -> UB.

    >
    > #include <stdlib.h>
    > #include <stdio.h>
    >
    > struct cells
    > {
    > int id;
    > int x;
    > int y;
    > int number_neighbours;
    > int *neighbour_id;
    > };
    >
    > int main(void)
    > {
    > struct cells *the_cells;
    > int i;
    > the_cells=calloc(10,sizeof(*the_cells));


    is undefined behavior!



    --
    Tschau/Bye
    Herbert

    eComStation 1.1 Deutsch wird jetzt ausgeliefert!
     
    The Real OS/2 Guy, Oct 1, 2003
    #6
  7. N Yiannakoulias

    James Lee Guest

    Hi,

    I am not sure why you are allocating ten pointers:

    struct cells *the_cells;
    the_cells=malloc(sizeof(*the_cells)*10);

    Isn't it more efficient to simply do this:

    typedef struct cells
    {
    int id;
    int x;
    int y;
    int number_neighbours;
    int *neighbour_id;
    } cell;

    cell *the_cells;
    the_cells = (cell *) malloc(sizeof(cell) * 10);

    In other words, why not just allocate enough memory for 10 cells?

    -j.

    N Yiannakoulias <> wrote in message news:<blca7c$ks7$>...
    > Hello all,
    >
    > I am trying to initialize a pointer inside an evil global structure. The
    > pointer neighbour_id is of different size for each of the 10 cells
    > initialized in the function main:
    >
    > struct cells
    > {
    > int id;
    > int x;
    > int y;
    > int number_neighbours;
    > int *neighbour_id;
    > };
    >
    > int main(void)
    > {
    > struct cells *the_cells;
    > the_cells=malloc(sizeof(*the_cells)*10);
    > /*check for memory availability...*/
    >
    > /*
    > For each element of the structure, there are different number of
    > neighbours (thus neighbour_id, a list of neighbour
    > identifiers, is a different size for each element of the
    > structure. How do I initialize this on a 'cell-by'cell' basis?
    > is it something like:
    > the_cells.neighbour_id=malloc(sizeof(??))*5) if I want to
    > allocate space for 5 'values' in the pointer?
    > */
    >
    > free(the_cells);
    > /*I'll also want to free memory used by the pointers in
    > the structure? Is that necessary?*/
    > return 0;
    > }
    >
    > Thanks for any guidance,
    >
    > N
     
    James Lee, Oct 1, 2003
    #7
  8. N Yiannakoulias

    James Lee Guest

    Does anybody want to comment on this? I am curious myself...

    -j.

    (James Lee) wrote in message news:<>...
    > Hi,
    >
    > I am not sure why you are allocating ten pointers:
    >
    > struct cells *the_cells;
    > the_cells=malloc(sizeof(*the_cells)*10);
    >
    > Isn't it more efficient to simply do this:
    >
    > typedef struct cells
    > {
    > int id;
    > int x;
    > int y;
    > int number_neighbours;
    > int *neighbour_id;
    > } cell;
    >
    > cell *the_cells;
    > the_cells = (cell *) malloc(sizeof(cell) * 10);
    >
    > In other words, why not just allocate enough memory for 10 cells?
    >
    > -j.
    >
    > N Yiannakoulias <> wrote in message news:<blca7c$ks7$>...
    > > Hello all,
    > >
    > > I am trying to initialize a pointer inside an evil global structure. The
    > > pointer neighbour_id is of different size for each of the 10 cells
    > > initialized in the function main:
    > >
    > > struct cells
    > > {
    > > int id;
    > > int x;
    > > int y;
    > > int number_neighbours;
    > > int *neighbour_id;
    > > };
    > >
    > > int main(void)
    > > {
    > > struct cells *the_cells;
    > > the_cells=malloc(sizeof(*the_cells)*10);
    > > /*check for memory availability...*/
    > >
    > > /*
    > > For each element of the structure, there are different number of
    > > neighbours (thus neighbour_id, a list of neighbour
    > > identifiers, is a different size for each element of the
    > > structure. How do I initialize this on a 'cell-by'cell' basis?
    > > is it something like:
    > > the_cells.neighbour_id=malloc(sizeof(??))*5) if I want to
    > > allocate space for 5 'values' in the pointer?
    > > */
    > >
    > > free(the_cells);
    > > /*I'll also want to free memory used by the pointers in
    > > the structure? Is that necessary?*/
    > > return 0;
    > > }
    > >
    > > Thanks for any guidance,
    > >
    > > N
     
    James Lee, Oct 2, 2003
    #8
  9. N Yiannakoulias

    Martijn Guest

    James Lee wrote:
    > Does anybody want to comment on this? I am curious myself...
    >


    You shouldn't top-post ;)

    [remainder snipped]

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Oct 4, 2003
    #9
    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. Replies:
    7
    Views:
    436
  2. DSKR

    Pointers to 'Data Structures' in C

    DSKR, Jun 24, 2003, in forum: C Programming
    Replies:
    31
    Views:
    10,124
    Giuseppe
    Jul 3, 2003
  3. tweak
    Replies:
    14
    Views:
    2,814
    Eric Sosman
    Jun 11, 2004
  4. Alfonso Morra
    Replies:
    11
    Views:
    740
    Emmanuel Delahaye
    Sep 24, 2005
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    714
Loading...

Share This Page