pointers in structures?

N

N Yiannakoulias

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
 
M

Martijn

N said:
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" :) said:
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,
 
E

Eric Sosman

Martijn said:
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));
^^^^
 
A

Al Bowers

N said:
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;
}
 
M

Martijn

Eric said:
Martijn said:
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...
 
T

The Real OS/2 Guy

N said:
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!
 
J

James Lee

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.
 
J

James Lee

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

-j.

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 said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top