I have a dynamic array of structures, so I thought I could store the information about the array in the first structure.
So one attribute will represent the amount of memory allocated for the array and another one representing number of the structures actually stored in the array.
The trouble is, that when I put it inside a function that fills it with these structures and tries to allocate more memory if needed, the original array gets somehow distorted.
Can someone explain why is this and how to get past it?
Here is my code
#define INIT 3
typedef struct point{
int x;
int y;
int c;
int d;
}Point;
Point empty(){
Point p;
p.x=1;
p.y=10;
p.c=100;
p.d=1000; //if you put different values it will act differently - weird
return p;
}
void printArray(Point * r){
int i;
int total = r[0].y+1;
for(i=0;i<total;i++){
printf("%2d | P [%2d,%2d][%4d,%4d]\n",i,r[i].x,r[i].y,r[i].c,r[i].d);
}
}
void reallocFunction(Point * r){
r=(Point *) realloc(r,r[0].x*2*sizeof(Point));
r[0].x*=2;
}
void enter(Point* r,int c){
int i;
for(i=1;i<c;i++){
r[r[0].y+1]=empty();
r[0].y++;
if( (r[0].y+2) >= r[0].x ){ /*when the amount of Points is near
*the end of allocated memory.
reallocate the array*/
reallocFunction(r);
}
}
}
int main(int argc, char** argv) {
Point * r=(Point *) malloc ( sizeof ( Point ) * INIT );
r[0]=empty();
r[0].x=INIT; /*so here I store for how many "Points" is there memory
//in r[0].y theres how many Points there are.*/
enter(r,5);
printArray(r);
return (0);
}
Your code does not look clean to me for other reasons, but…
The problem here is that
rin this function is the parameter, hence any modifications to it are lost when the function returns. You need some way to change the caller’s version ofr. I suggest:Then later:
Now… Another thing to consider is that
realloccan fail. A common pattern forreallocthat accounts for this is:This ensures that you don’t leak
rwhen the memory allocation fails, and the caller then has to decide what happens when your function returnsNULL…But, some other things I’d point out about this code (I don’t mean to sound like I’m nitpicking about things and trying to tear them apart; this is meant as constructive design feedback):
reallocFunctiondoesn’t seem to really make sense. Perhaps the name and interface can be clearer. When do you need torealloc? Why do you double the X member? Why do you increment Y? Can the caller make these decisions instead? I would make that clearer.enter()is supposed to be doing. Maybe the names could be clearer.main()has a lot of knowledge of your structure’s internals. That seems bad.reallocin the way that you do is sometimes a red flag… It’s a corner case, but the multiplication can overflow and you can end up shrinking the buffer instead of growing it. This would make you crash and in writing production code it would be important to avoid this for security reasons.