2

Having an array as:

type **a;

a[0][data_0]
a[1][data_1]
a[2][data_2]
a[n][data_n]

When extending such an array by doing:

  1. realloc() on a to sizeof(type*) * (n + 1).
  2. malloc() (*a[n]) to fit data_n where data_n is of variable size.

Could there be some issue with realloc() of a?

As in a[2] would always point to data_2, even if a gets moved in memory, or could that link be lost?

As I understand it I end up with something like this in memory:

         Address               Address
a[0] => 0x###131, (*a[0]) => 0x####784
a[1] => 0x###135, (*a[1]) => 0x####793
a[2] => 0x###139, (*a[2]) => 0x####814

After realloc() I could end up with something like:

         Address               Address
a[0] => 0x###216, (*a[0]) => 0x####784
a[1] => 0x###21a, (*a[1]) => 0x####793
a[2] => 0x###21e, (*a[2]) => 0x####814
a[n] => 0x###zzz, (*a[n]) => 0x####yyy

Is this correct? The data_n segments are left alone, or could they also get moved?

3 Answers 3

2

Is this correct? The data_n segments are left alone, or could they also get moved?

Yes, the values of a[i], for 0 <= i < n are copied to the new location, so the pointers point to the same data_i and those will not be moved.

Could there be some issue with realloc() of a?

Of course, a realloc can always fail and return NULL, so you should never do

a = realloc(a, new_size);

but use a temporary variable to store the return value of realloc.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Had to be 100% sure. Also as in if I have a separate ptr to data_nn it wont be corrupted after growing a. (I did a booboo by realloc() on a linked list - not to smart.)
Right, it won't be corrupted. realloc only knows the address and size of the current block, and the requested new size, it doesn't know what kind of data is stored there, so if it moves the block, it just copies the data (probably using memcpy).
2

If you are reallocing to a larger size, the original bytes are unchanged.

Example:

char **a = malloc(n*sizeof(char *));
for (i=0; i!=n; ++i) {
  a[i] = malloc(m);
}

a = realloc(a,(n+1)*sizeof(char *));
// a[0]...a[n-1] are still the same
a[n] = malloc(m);

Comments

1

Yeah the address of old values remains same even after realloc()

You can see in the output of this program:

shubhanshm@BANLSHUBHANSH /cygdrive/f/My Codes/Practice/C
$ ./a.exe
Original Array details before using realloc():
Printing array with size 4x4
1       0       0       19
2       4       0       19
3       6       9       27
4       8       12      16
Printing array addresses with size 4x4
a[0][0]=1       ->0x20010260
a[0][1]=0       ->0x20010264
a[0][2]=0       ->0x20010268
a[0][3]=19      ->0x2001026c

a[1][0]=2       ->0x20010270
a[1][1]=4       ->0x20010274
a[1][2]=0       ->0x20010278
a[1][3]=19      ->0x2001027c

a[2][0]=3       ->0x20010280
a[2][1]=6       ->0x20010284
a[2][2]=9       ->0x20010288
a[2][3]=27      ->0x2001028c

a[3][0]=4       ->0x20010290
a[3][1]=8       ->0x20010294
a[3][2]=12      ->0x20010298
a[3][3]=16      ->0x2001029c

Array details after using realloc():
Printing array with size 5x4
1       0       0       19
2       4       0       19
3       6       9       27
4       8       12      16
5       10      15      20
Printing array addresses with size 5x4
a[0][0]=1       ->0x20010260
a[0][1]=0       ->0x20010264
a[0][2]=0       ->0x20010268
a[0][3]=19      ->0x2001026c

a[1][0]=2       ->0x20010270
a[1][1]=4       ->0x20010274
a[1][2]=0       ->0x20010278
a[1][3]=19      ->0x2001027c

a[2][0]=3       ->0x20010280
a[2][1]=6       ->0x20010284
a[2][2]=9       ->0x20010288
a[2][3]=27      ->0x2001028c

a[3][0]=4       ->0x20010290
a[3][1]=8       ->0x20010294
a[3][2]=12      ->0x20010298
a[3][3]=16      ->0x2001029c

a[4][0]=5       ->0x20048300
a[4][1]=10      ->0x20048304
a[4][2]=15      ->0x20048308
a[4][3]=20      ->0x2004830c

The source code for the above output is:

#include<stdio.h>
#include<stdlib.h>

#define mul(x, y) (((x)+1)*((y)+1))

void printArr(int **a, int r, int c){
    int i, j;
    printf("Printing array with size %dx%d\n", r, c );
    for(i = 0; i < r; i++){
        for(j = 0; j < c; j++){
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }
}

void printArrAddress(int **a, int r, int c){
    int i, j;
    printf("Printing array addresses with size %dx%d\n", r, c );
    for(i = 0; i < r; i++){
        for(j = 0; j < c; j++){
            printf("a[%d][%d]=%d\t->%p\n", i, j, a[i][j], &a[i][j]);
        }
        printf("\n");
    }
}

int main(){
    int **a;
    int n = 4;
    a = (int**)malloc(sizeof(int*)*n);
    int i, j;
    for(i = 0; i< n; i++){
        a[i] = (int*)malloc(sizeof(int)*(i+1));
        for(j = 0; j < i+1; j++ )a[i][j] = mul(i, j);
    }
    printf("Original Array details before using realloc():\n");
    printArr(a, n, n);
    printArrAddress(a, n, n);

    a = (int**)realloc(a, sizeof(int*)*(n+1));
    a[n] = (int*)malloc(sizeof(int)*n);
    for( i = 0; i< n; i++){
        a[n][i] = mul(n, i);
    }
    printf("Array details after using realloc():\n");
    printArr(a, n+1, n);
    printArrAddress(a, n+1, n);
    return 0;
}

I hope this clarifies things.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.