Path: utzoo!utgpu!jarvis.csri.toronto.edu!smoke.cs.toronto.edu!neat.cs.toronto.edu!moraes Newsgroups: comp.lang.c From: moraes@cs.toronto.edu (Mark Moraes) Subject: Re: realloc questions Message-ID: <90Mar2.060540est.600@smoke.cs.toronto.edu> Organization: Department of Computer Science, University of Toronto References: <4563@rouge.usl.edu> <1990Mar1.224759.947@oracle.com> Date: 2 Mar 90 11:06:14 GMT Lines: 115 Sigh. After two incorrect/partial answers, I couldn't resist. When posting code fragments that you have problems with, it might be a good idea to make sure they compile first. Also, please pass them through either lint or an ANSI C compiler with good warnings and prototyped header files. (If your C environment has neither, then you're working in an unsupportive environment and are asking for trouble -- lint is a good friend. People who don't realize how much of a friend it can be should see refs 1 and 2 below) The code posted in <4563@rouge.usl.edu> a) wouldn't compile b) produced several serious lint errors (marked with ? and annotating comments below) c) contained at least one serious logical error. A good example of how people seem to be confused about C pointers, arrays, malloc and realloc. typedef struct a { int row, col; long **arr} A; A *temp; temp=(A *) calloc (1, sizeof(A)); /* then initialize row and col ... */ A->arr=(long *)calloc (A->row, sizeof(long *)); ? /* cast to long **, not (long *) */ for (j=0;jrow;j++) A->arr[j] = calloc(col,sizeof(long)); A->arr=(long *) realloc ((char *)&A->arr, new_row*sizeof(long *)); ? ? /* No need for & */ for (j=0;jnew_row;j++) ??????? /* * The pointers in temp->arr[] from row to * new_row will contain undefined values, * since realloc(temp->arr) does not zero the * grown space. All realloc guarantees is * that the first MIN(old size, new size) * bytes will contain exactly what they did * before the realloc. Also, many reallocs do not * guarantee ANSI C semantics of realloc(NULL, * n) => malloc(n) */ A->arr[j] = realloc(new_col,sizeof(long)); ??????? /* Ouch! What are you reallocing? */ The following is a version that at least passes a C compiler and lint cleanly (modulo usual warnings about pointer alignment) -- it should work. Run through cb -s for good measure. (To keep it reasonably short, I've committed the heinous "Can't happen" sin of not checking the calloc/realloc error returns. Any self respecting production program would check those, of course) typedef char * pointer; /* void * in ANSI C */ extern pointer calloc(); extern pointer realloc(); extern void free(); /* returns int in older implementations */ typedef struct { unsigned int row, col; long **arr; } A; int main() { A *temp; unsigned int new_col, new_row; int j; temp = (A *) calloc ((unsigned) 1, sizeof(A)); /* then initialize row and col ... */ temp->row = 5; temp->col = 10; temp->arr = (long **) calloc (temp->row, sizeof(long *)); for (j = 0; j < temp->row; j++) temp->arr[j] = (long *) calloc(temp->col, sizeof(long)); /* * now you can access temp->arr[j][k] for 0 <= j < temp->row and 0 * <= k < temp->col. */ new_row = 10; new_col = 20; /* grow vector of pointers to rows */ temp->arr = (long **) realloc ((pointer)temp->arr, new_row * sizeof(long *)); /* * grow old rows -- if new_row could be less than temp->row, we'd * have a to be a little more careful */ for (j = 0; j < temp->row; j++) temp->arr[j] = (long *) realloc((pointer) temp->arr[j], new_col * sizeof(long)); /* allocate new rows */ for(j = temp->row; j < new_row; j++) temp->arr[j] = (long *) calloc(new_col, sizeof(long)); /* * just as a tutorial (xref the Turbo C malloc thread), we free the * arrays. Remember the simple rule -- if you didn't get the * pointer from malloc/calloc or realloc, you CANNOT free it. */ for(j = 0; j < new_row; j++) free((pointer) temp->arr[j]); free((pointer) temp->arr); free((pointer) temp); return 0; } Refs: 1. Ian Darwin and Geoff Collyer, "Can't Happen or /* NOTREACHED */ or Real Programs Dump Core" USENIX Association Winter Conference, Dallas 1985 Proceedings. 2. Ian Darwin, "Checking C Programs with lint", O'Reilly Books.