Reputation: 125
currently I am trying to resize a 2D Array in C using this code snippet
array = (int**) realloc(array, s * 2 * sizeof(int));
Where s is the size of the array in rows and colums. However, when trying to access the new areas of the array like this,
array[3][0] = x;
I only get a segfault. The old areas of the array work fine. How can I solve this issue?
Upvotes: 1
Views: 9936
Reputation: 1405
Here is an example of a function to resize a 2D array in C:
int** ResizeGrid(int** A, uint64_t rows, uint64_t cols, uint64_t newRow, uint64_t newCol)
{
// If old size is same as new size, return the same grid
// if (newRow == rows && newCol == cols) {
// return A;
// }
// If new size is smaller than old size, free the extra memory
if (rows > newRow) {
for (uint64_t i = newRow; i < rows; i++) {
free(A[i]);
}
return A;
}
A = (int**)realloc(A, sizeof(int*) * newRow);
// Check if realloc fails
if (A == NULL) {
return NULL;
}
for (uint64_t i = 0; i < newRow; i++) {
// Reallocate memory only on already allocated rows
if (rows > i) {
A[i] = (int*)realloc(A[i], sizeof(int) * newCol);
} else {
A[i] = (int*)malloc(sizeof(int) * newCol);
}
// Check if realloc/malloc fails
if (A[i] == NULL) {
// Free all the rows that have been allocated
for (uint64_t j = 0; j < i; j++) {
free(A[j]);
}
free(A);
return NULL;
}
}
return A;
}
An example implementation of the function
Upvotes: 0
Reputation: 123458
Assuming you declared array
as
int **array;
and allocated as
array = malloc( sizeof *array * ROWS );
if ( array )
{
for ( size_t i = 0; i < ROWS; i++ )
array[i] = malloc( sizeof *array[i] * COLS );
}
The structure you wind up with looks something like:
+---+ +---+ +---+
array: | | -----> | | array[0] ------> | | array[0][0]
+---+ +---+ +---+
... | | array[1] ---+ | | array[0][1]
+---+ | +---+
... | | | array[0][2]
| +---+
| ...
|
| +---+
+--> | | array[1][0]
+---+
| | array[1][1]
+---+
| | array[1][2]
+---+
...
If you want to increase the number of rows in the array but leave the column sizes the same, you'd do something like
int **tmp = realloc( array, sizeof *array * (ROWS + add_rows) );
if ( tmp )
{
array = tmp;
for ( size_t i = 0; i < add_rows; i++ )
{
array[ROWS + i] = malloc( sizeof *array[ROWS + i] * COLS );
}
}
If you want to leave the number of rows the same but increase the number of columns in each row, you would do something like
for ( size_t i = 0; i < ROWS; i++ )
{
int *tmp = realloc( array[i], sizeof *array[i] * (COLS + add_cols) );
if ( tmp )
{
array[i] = tmp;
}
}
If you want to reduce the number of rows in the array, you will need to free the affected rows first:
for ( size_t i = 1; i <= del_rows; i++ )
free( array[ROWS - i] );
int *tmp = realloc( array, ROWS - del_rows );
if ( tmp )
array = tmp;
If you want to reduce the number of columns:
for ( size_t i = 0; i < ROWS: i++ )
{
int *tmp = realloc( array[i], sizeof *array[i] * (COLS - del_cols) );
if ( tmp )
array[i] = tmp;
}
From there, you should be able to figure out any combinations you need. I strongly recommend doing only one dimension at a time (that is, if you want to increase the number of rows and columns, do the rows first, then do the columns).
You always want to assign the result of realloc
to a temporary variable; if realloc
cannot satisfy the request, it will return NULL
, and if you assign it back to the original variable, you will lose your only reference to the memory that was previously allocated, leading to a memory leak.
Upvotes: 16