calloc problem

K

kdogksu

I am trying to dynamically allocate memory to be used as an array.
The array is pointed to by the 'vert' member of the structure 'grid'.
I wish for this array to be a 2 dimensional array of the struct
vertex. The relevant parts of my code follow:

typedef struct {
int upPoints, downPoints, leftPoints, rightPoints;
int upLines, downLines, leftLines, rightLines;
} vertex;

typedef struct {
int xSize, ySize;
vertex** vert;
} grid;

.
.
.

g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex**));
for (n=0; n < g.xSize-1; n++)
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex*));

Where g is a grid.

I then try to assign values to the members of vertex. However,
assigning a single point in this manner:

g->vert[x][y].upPoints++;

results in data that looks as follows:

(Each four-digit group is upPoints, downPoints, leftPoints, and
rightPoints of a single vertex struct run together. The position of
the four digit groups correllate to X and Y with 0,0 in the lower left
hand corner, cartesian coordinate style)

0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000

As you can see, incrementing one member of a single vertex causes the
same member of several other vertices to be incremented as well.

After beating my head against the wall (only figuratively) for a
couple hours looking at the code that increments the member, I finally
thought to check the memory. Printing the values of the pointers to
these vertices results in the following:

(I cut off the rightmost columns for nice formatting on the page)

134523880 134523944 134524008 134524072 134524136 134524200
134523848 134523912 134523976 134524040 134524104 134524168
134523816 134523880 134523944 134524008 134524072 134524136
134523784 134523848 134523912 134523976 134524040 134524104
134523752 134523816 134523880 134523944 134524008 134524072
134523720 134523784 134523848 134523912 134523976 134524040
134523688 134523752 134523816 134523880 134523944 134524008
134523656 134523720 134523784 134523848 134523912 134523976
134523624 134523688 134523752 134523816 134523880 134523944
134523592 134523656 134523720 134523784 134523848 134523912
134523560 134523624 134523688 134523752 134523816 134523880
134523528 134523592 134523656 134523720 134523784 134523848
134523496 134523560 134523624 134523688 134523752 134523816
134523464 134523528 134523592 134523656 134523720 134523784
134523432 134523496 134523560 134523624 134523688 134523752

Calloc has given the same memory to multiple pointers. (Any address
is the same as the one two down and one right of it, the same pattern
as the data in the vertex array). What is causing this? How can I
get calloc to give seperate memory for all vertex instances? Any help
would be appreciated. Thanks.

P.S. I hope this description is adequate. Feel free to ask for
clarification.
 
J

James Hu

I am trying to dynamically allocate memory to be used as an array.
The array is pointed to by the 'vert' member of the structure 'grid'.
I wish for this array to be a 2 dimensional array of the struct
vertex. The relevant parts of my code follow:

You should consult the C-faq. In particular, read the answer to
question 6.16.

http://www.eskimo.com/~scs/C-faq/top.html
http://www.eskimo.com/~scs/C-faq/q6.16.html
typedef struct {
int upPoints, downPoints, leftPoints, rightPoints;
int upLines, downLines, leftLines, rightLines;
} vertex;

typedef struct {
int xSize, ySize;
vertex** vert;
} grid;

.
.
.

g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex**));

You should use:
g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex*));

Although in practice, it should rarely be the case that those sizes
would differ (I actually can't think of any reasonable scenario where
they would, but perhaps someone else can).
for (n=0; n < g.xSize-1; n++)
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex*));

You want:
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex));


The casts are unnecessary in C, but harmless enough so long as a
prototype for calloc is present (e.g., if the <stdlib.h> header is
present).

-- James
 
M

Martin Ambuhl

kdogksu said:
I am trying to dynamically allocate memory to be used as an array.
The array is pointed to by the 'vert' member of the structure 'grid'.
I wish for this array to be a 2 dimensional array of the struct
vertex. The relevant parts of my code follow:

typedef struct {
int upPoints, downPoints, leftPoints, rightPoints;
int upLines, downLines, leftLines, rightLines;
} vertex;

typedef struct {
int xSize, ySize;
vertex** vert;
} grid;

.
.
.

g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex**));
for (n=0; n < g.xSize-1; n++)
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex*));

Where g is a grid.

Your code has got to be wrong. Notice (with the superfluous and cast
still used and probably wasteful use of calloc rather than malloc):
{
T *x;
x = (T *)calloc(n, sizeof(T));
}
The cast is to (T *), the allocation of of n*sizeof(T)

For your case (where the xSize is Q, defined elsewhere)

grid g = {.xsize = Q};
if (!(g.vert = malloc((g.xSize-1) * sizeof *g.vert)))
{ /* handle error */}
for (n=0; n < g.xSize-1; n++)
if(!(g.vert[n] = malloc((g.ySize-1) * sizeof *g.vert[n])))
{ /* handle error */ }
 
A

Al Bowers

James said:
I am trying to dynamically allocate memory to be used as an array.
The array is pointed to by the 'vert' member of the structure 'grid'.
I wish for this array to be a 2 dimensional array of the struct
vertex. The relevant parts of my code follow:


You should consult the C-faq. In particular, read the answer to
question 6.16.

http://www.eskimo.com/~scs/C-faq/top.html
http://www.eskimo.com/~scs/C-faq/q6.16.html

typedef struct {
int upPoints, downPoints, leftPoints, rightPoints;
int upLines, downLines, leftLines, rightLines;
} vertex;

typedef struct {
int xSize, ySize;
vertex** vert;
} grid;

.
.
.

g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex**));


You should use:
g.vert = (vertex**)calloc((g.xSize-1), sizeof(vertex*));

Although in practice, it should rarely be the case that those sizes
would differ (I actually can't think of any reasonable scenario where
they would, but perhaps someone else can).

for (n=0; n < g.xSize-1; n++)
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex*));


You want:
g.vert[n] = (vertex*)calloc((g.ySize-1), sizeof(vertex));

This looks fine. It would seem that the OP wants g.xSize to
represent one dimension and g.ySize the other dimension.
Therefore, I,m very curious on why the OP wants
to allocate ySize-1 instead of ySize and xSize-1 instead of
xSize.
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top