Newsgroups: comp.lang.c Path: utzoo!sq!msb From: msb@sq.sq.com (Mark Brader) Subject: Re: realloc questions Message-ID: <1990Mar6.063648.16148@sq.sq.com> Reply-To: msb@sq.com (Mark Brader) Organization: SoftQuad Inc., Toronto References: <4563@rouge.usl.edu> <1990Mar1.224759.947@oracle.com> Distribution: usa Date: Tue, 6 Mar 90 06:36:48 GMT [Karl Heuer: if you see this, let me know.] [Anyone: if you see this twice, my apologies.] > > temp->arr=(long *) realloc ((char *)&temp->arr, new_row*sizeof(long *)); > > for (j=0;jnew_row;j++) > > temp->arr[j] = realloc(new_col,sizeof(long)); > You're re-allocating temp->arr before you re-allocate temp->arr[j]! > Just switch the order of the realloc() calls and you should be fine. No, it's more complicated than that. You only want to use realloc() on only those rows that existed and will continue to exist. If there are new rows, you have to malloc() them. (Well, there are other ways to arrange it, but they aren't any easier.) Conversely, for the ones that are ceasing to exist, you want to free() them. Also, the first call to realloc() is has an extra & and its result is wrongly cast, and the second call is worse, having the arguments of calloc() instead of realloc(). And temp->new_row is also wrong. (Please let your compilers get the syntax errors out of your code before you post it! The code below has been compiled and (lightly) tested.) Try this: /* if number of rows is about to shrink, get rid of old ones * (else, the loop will iterate 0 times) */ for (j = new_row; j < temp->row; ++j) free ((char *) temp->arr[j]); /* adjust number of rows */ temp->arr = (long **) realloc ((char *) temp->arr, new_row * sizeof (long *)); /* if number of rows has just grown, allocate new ones * (else, the loop will iterate 0 times) */ for (j = temp->row; j < new_row; ++j) temp->arr[j] = (long *) malloc (new_col * sizeof (long)); /* adjust length of rows that exist and will continue to exist * (while the three operations above must be in the order shown, * this one could go at any point above or below them) */ for (j = 0; j < temp->row && j < new_row; ++j) temp->arr[j] = (long *) realloc ((char *) temp->arr[j], new_col * sizeof (long)); /* update row and column information */ temp->row = new_row; temp->col = new_col; Another approach is to just free the whole structure and start over. Since the original posting used calloc(), not malloc(), to allocate the space, it may have been important that the array be initialized so zeroes. If realloc() enlarges the allocated space, the added space is uninitialized. In the above, I have elected to assume that no initialization was really desired, and used malloc() and realloc(). If initialization IS really desired, the malloc(a*b) call should be changed to calloc(a,b), and the last for-loop should become: for (j = 0; j < temp->row && j < new_row; ++j) { register int k; temp->arr[j] = (long *) realloc ((char *) temp->arr[j], new_col * sizeof (long)); for (k = temp->col; k < new_col; ++k) temp->arr[j][k] = 0; } or the equivalent thereof. Depending on how your malloc() works, starting over may give better results anyway, by maximizing malloc()'s chances to coalesce the allocated chunks of memory. Then again, it may not. -- Mark Brader "I always pass on good advice. It's the only thing SoftQuad Inc., Toronto to do with it. It is never any use to oneself." utzoo!sq!msb, msb@sq.com -- Lord Goring (Oscar Wilde: An Ideal Husband) This article is in the public domain.