在C中调整2D数组的大小



目前我正在尝试在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;
}

函数

的示例实现

相关内容

  • 没有找到相关文章