【问题标题】:Expanding 2D array with realloc gives me a memory leak使用 realloc 扩展二维数组会导致内存泄漏
【发布时间】:2022-01-13 02:22:16
【问题描述】:
board = (char**)realloc(board, numbers[0] * sizeof (char*));
    for (int i = 0; i < numbers[0]; i++) {
        board[i] = (char*)malloc(numbers[1] * sizeof (char));
    }

board 是 [y][x] 但我想扩展它,所以它是 [numbers[0]][numbers[1]],但是这段代码给了我内存泄漏(它来自这个我检查过) . 为什么以及如何正确地做到这一点?

以后就这样免费了:

for(int i = 0; i < sizeY; i++){
              free(board[i]);
        }
        free(board);

它是这样创建的:

char** board = (char**)malloc(boardY * sizeof * board); 
for (int i = 0; i < boardSizeY; i++) { 
board[i] = (char*)malloc(boardX * sizeof * *board); 
}

【问题讨论】:

  • 我不太明白,那该怎么做呢?

标签: c++ c memory


【解决方案1】:

以下是对现有代码的一些评论:

// assume at this point that board[0] is pointing to a malloc()'d
// buffer, as is board[1], board[2], and so on

// below here you call realloc(), which resizes the
// pointer-array either larger or smaller.  If it makes
// it smaller, then you've lost access to the pointers
// that were at the end of the old array, so the
// buffers they pointed to have been leaked.

board = (char**)realloc(board, numbers[0] * sizeof (char*));
for (int i = 0; i < numbers[0]; i++) {
    // In any case, here you are overwriting all the pointers
    // in (board), so any buffers they previously pointed to
    // are now leaked (because no longer have access to them,
    // so you can never call free() on them after this)
    board[i] = (char*)malloc(numbers[1] * sizeof (char));
}

...那么,该怎么做呢?像这样的东西怎么样:

// before updating numbers[0] or numbers[1], we'll
// free any old allocations we had
for (int i = 0; i < numbers[0]; i++) {
   free(board[i]);
}

// update numbers[0] and numbers[1] to their new values...
numbers[0] = [...]
numbers[1] = [...];

// now we can resize board and allocate new sub-buffers
board = (char**)realloc(board, numbers[0] * sizeof (char*));
for (int i = 0; i < numbers[0]; i++) {
   board[i] = (char*)malloc(numbers[1] * sizeof (char));
}

当然,将二维数组存储为指向数组的指针数组无论如何都过于复杂且效率低下,因为您可以将所有数据存储在单个分配中:

size_t arraySize = numbers[0] * numbers[1];
char * board = (char *) malloc(numbers[0] * numbers[1]);
...
free(board);

char getValueAt(const char * board, int sizeX, int x, int y)
{
   return board[(x*sizeX)+y];
}

void setValueAt(char * board, int sizeX, int x, int y, char newValue)
{
   board[(x*sizeX)+y] = newValue;
}

【讨论】:

  • 我在 realloc 之前添加了这个 for 循环,但我仍然遇到内存泄漏
  • 如果您在问题中包含一个最小的、可编译的示例,我可以在我的计算机上编译和运行它并调查发生的任何内存泄漏。没有它,我只能猜测,所以这是我的猜测:您的程序包含错误。
【解决方案2】:
board = (char**)realloc(board, numbers[0] * sizeof (char*));

这不好,因为board中的每个指针都丢失了,而且正如你所说的那样会导致内存泄漏。

我认为有两种方法。

  1. free()boardrealloc 之前的所有指针。
for(int i = 0; i < sizeY; i++){
   free(board[i]);
}
board = (char**)realloc(board, numbers[0] * sizeof (char*));
for (int i = 0; i < numbers[0]; i++) {
    board[i] = (char*)malloc(numbers[1] * sizeof (char));
}
  1. realloc()之前保存所有指向另一个数组的指针并在realloc()之后恢复它们
char **temp = (char **)malloc(numbers[0] * sizeof(char *));
for (int i = 0; i < numbers[0]; i++) {
  temp[i] = board[i];
}
board = (char**)realloc(board, numbers[0] * sizeof (char*));
for (int i = 0; i < numbers[0]; i++) {
  board[i] = temp[i];
}
free(temp);

【讨论】:

  • 你完全正确,我错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2010-11-18
  • 1970-01-01
相关资源
最近更新 更多