目前我正在尝试在C中使用此代码片段调整2D数组的大小
array = (int**) realloc(array, s * 2 * sizeof(int));
其中s为数组的行和列大小。但是,当尝试像这样访问数组的新区域时,
array[3][0] = x;
我只得到一个段错误。阵列的旧区域工作良好。如何解决这个问题?
假设您将array
声明为
int **array;
并分配为
array = malloc( sizeof *array * ROWS );
if ( array )
{
for ( size_t i = 0; i < ROWS; i++ )
array[i] = malloc( sizeof *array[i] * COLS );
}
你最终得到的结构看起来像:
+---+ +---+ +---+
array: | | -----> | | array[0] ------> | | array[0][0]
+---+ +---+ +---+
... | | array[1] ---+ | | array[0][1]
+---+ | +---+
... | | | array[0][2]
| +---+
| ...
|
| +---+
+--> | | array[1][0]
+---+
| | array[1][1]
+---+
| | array[1][2]
+---+
...
如果想增加数组中的行数,但保持列大小不变,您可以执行如下操作
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 );
}
}
如果您想保持行数不变,但增加列的数量在每行中,您可以执行如下操作
for ( size_t i = 0; i < ROWS; i++ )
{
int *tmp = realloc( array[i], sizeof *array[i] * (COLS + add_cols) );
if ( tmp )
{
array[i] = tmp;
}
}
如果您想减少数组中的行数,您需要首先释放受影响的行:
for ( size_t i = 1; i <= del_rows; i++ )
free( array[ROWS - i] );
int *tmp = realloc( array, ROWS - del_rows );
if ( tmp )
array = tmp;
如果你想减少列数:
for ( size_t i = 0; i < ROWS: i++ )
{
int *tmp = realloc( array[i], sizeof *array[i] * (COLS - del_cols) );
if ( tmp )
array[i] = tmp;
}
从那里,你应该能够找出你需要的任何组合。我强烈建议一次只执行一个维度(也就是说,如果希望增加和列的数量,请先执行行,然后执行列)。
你总是想把realloc
的结果赋值给一个临时变量;如果realloc
不能满足请求,它将返回NULL
,如果将其赋值回原始变量,您将失去对先前分配的内存的唯一引用,从而导致内存泄漏。
下面是一个用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;
}
函数