0

I was trying to implement Viterbi decoder in C.

So I thought of using a 2-dimensional array which i wanted to create dynamically. Here is the sample code for 2D array created dynamically:

place_table = (int **)malloc((no_places+1)*sizeof(int *));

for(i = 1; i <= no_places; i++)
    place_table[i] = (int *)malloc((no_places+1)*sizeof(int));

The size of this 2-dimensional array keeps on varying in my decoder, i.e., no_places keeps on varying, so I wanted to know how to reallocate memory for the 2-dimensional array.

Any suggestion or help would be greatly appreciated.

ajay
  • 9,402
  • 8
  • 44
  • 71
shreyas
  • 115
  • 1
  • 8
  • 2
    Most likely using `realloc`. – jweyrich Feb 18 '14 at 17:29
  • 1
    Are you talking about `2d array`? – herohuyongtao Feb 18 '14 at 17:30
  • S 2d array created using 2 dimensional pointer – shreyas Feb 18 '14 at 17:31
  • 1
    Any attempted code you can show? –  Feb 18 '14 at 17:36
  • When I hear a 2D array, I'm thinking of an array that contains nothing but pointers, and for each of those pointers, you allocate a separate array of size 'q'. So the array is not "square", as in: it's not an 'n by m' array: the first element could hold 12 items, the second element could hold 50, etc. Do you mean this type of 2D array, or do you want a "square" array that is `myArray[row * col]` in size? – OnlineCop Feb 18 '14 at 17:37
  • 2
    An array of pointers to arrays is not the same as a 2D array. Sounds like you have the former. – Dmitri Feb 18 '14 at 17:41
  • Your terminology isn't common. To avoid confusion it's best to refrain from calling any C objects "2D". Stick to arrays, pointers, arrays of arrays, arrays of pointers, pointers to pointers, and pointers to arrays. This way everyone can reasonably hope to understand what everyone else is talking about. – n. m. could be an AI Feb 18 '14 at 17:42
  • 1
    There's nothing called *2D pointer*. Do you mean a pointer to a pointer or a 2D array? They are different types. – ajay Feb 18 '14 at 17:45
  • It's not clear from your question whether you want to allocate or reallocate memory for a 2-D array. – ajay Feb 18 '14 at 17:57

1 Answers1

2

You can dynamically allocate memory for a 2-D array as (C99) :

int no_places;
int n = no_places + 1;  // for brevity in the following statement
int (*place_table)[n] = malloc(sizeof(int[n][n]));

// check for NULL
if(place_table == NULL) {
    // there's a problem
    // handle it
}
else {
    // you are good to go
}

It won't be correct to reallocate memory for the 2-D array place_table because with change in the dimension, the values in the older array will be reinterpreted as if they were elements of the new array. This will cause the rows to wrap around. (courtesy Pete Kirkham). Therefore, you need to allocate a new array and copy the values from the old array to it, then free the old array.

int old_n = n;
// value of n has been changed
// allocate a new array
int (*new_place_table)[n] = malloc(sizeof(int[n][n]));

// check for NULL and accordingly proceed
// if not NULL, copy place_table to new_place_table

for(int i = 0; i < old_n; i++) {
    for(int j = 0; j < old_n; j++) {
        new_place_table[i][j] = place_table[i][j];
    }
}

free(place_table);

// do stuff with new_place_table

free(new_place_table); 

Also note that you don't need to cast the result of malloc. There's no benefit of doing this and it can lead to bugs, undefined behaviour and program crash if you forget to include the stdlib.h header file. Read the details here.

Community
  • 1
  • 1
ajay
  • 9,402
  • 8
  • 44
  • 71
  • 2
    Firstly, if realloc fails you've lost your reference to the storage formerly pointed to by `place_table`. Secondly, the values will wrap around by the change in the length of each row with a typical contiguous 2D array implementation so you probably will want to allocate new storage and copy the values over rather than reallocating in place. – Pete Kirkham Feb 18 '14 at 18:19
  • @PeteKirkham To your first point, I'm not sure but I think `realloc` leaves `place_table` untouched if it fails to allocate enough memory. To your second point, yes you are right. – ajay Feb 18 '14 at 18:24
  • 2
    no, `realloc` returns 0 if it fails, so place_table will be 0 and you won't have any way of getting at the storage previously pointed to by place_table. You should store the result of realloc in a temporary then assign after testing it for 0. – Pete Kirkham Feb 18 '14 at 18:26
  • @PeteKirkham Yes, right. Thanks for clearing it up :) I will update my answer. – ajay Feb 18 '14 at 18:28