【问题标题】:Where to free memory, while creating 2d array? valgrind error创建二维数组时在哪里释放内存? valgrind 错误
【发布时间】:2021-03-29 14:05:54
【问题描述】:

我开始学习动态内存分配。在这段代码中,我在 ma​​in 函数中创建了二维数组:

int r, c;
scanf("%d %d\n", &r, &c);
size_t row = (size_t) r;
size_t col = (size_t) c;
int **board = malloc(row * sizeof(*board));                                                                       
for (int i = 0; i < r; i++) {                                                                                                     
   board[i] = malloc(col * sizeof(*board[i]));
}

(由于 for 循环,我需要 int 和 size_t,尤其是当 r>=0 时,这对于 size_t 总是如此)。

然后我将板子换成其他功能。 Valgrind 回归:

==59075== 364 (56 direct, 308 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2                    
==59075==    at 0x483577F: malloc (vg_replace_malloc.c:299)                                                             
==59075==    by 0x10B4DB: main (name22.c:122)                                                                        
==59075==  

122 行是:

int **board = malloc(row*sizeof( *board));

我想我必须使用 free(),但是在检查了其他我不知道的答案之后,我的错误在哪里以及将 free() 放在哪里,如果在程序的其余部分使用此表。我会很感激你的提示和解释。 `

【问题讨论】:

  • 如果你改变了board的地址,那么创建的内存现在是孤立的。提供足够多的代码来说明问题,至少一个minimal reproducible example
  • 如果你一直使用内存块直到你的程序结束,那么你应该调用free作为你在函数main中做的最后一件事。在调用free之后,任何情况下都不能访问内存块,否则你的程序会导致undefined behavior。另外,请记住不要只调用一次free,而是每次调用malloc 一次。所以你也必须循环调用它,就像你对malloc所做的那样。

标签: c multidimensional-array malloc dynamic-memory-allocation


【解决方案1】:

当您调用int **board = malloc(row * sizeof(*board)); 时,系统将为您分配row * sizeof(*board) 字节的内存,然后返回指向该内存开头的指针(即内存地址),您将其存储在int ** 变量中叫board

当您的程序完成时,系统会回收该内存,因此如果您的程序是短暂的,这可能并不重要,但养成释放内存的习惯是个好习惯,因为它不会回收任何内存直到你的程序退出,除非你告诉它

因此,您应该始终调用free(...),并在您使用完该内存后传入您第一次调用malloc(...) 时获得的内存地址。在大多数情况下,对malloc(...) 的每次调用都应该对free(...) 进行相等且相反的调用

这很重要,因为您的系统的内存量是有限的。如果您的程序要求资源,然后在完成后从不归还,您最终会耗尽内存 - 这就是所谓的“内存泄漏”。

所以对你来说,正确地调用free(...),看起来像这样:

int **board = malloc(row * sizeof(*board));                                                                       
for (int i = 0; i < r; i++) {                                                                                                     
   board[i] = malloc(col * sizeof(*board[i]));
}

// Do something with board

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

【讨论】:

  • 当您调用 int **board = malloc(row * sizeof(*board)); 时,系统将分配一块足以容纳 row 指针数量的内存块。(我认为这就是您的意思)。然后它分配row个块来保存colint,并依次为每个指针分配起始地址。然后释放,你以相反的顺序工作,释放每个块colint 在指针上调用 free 之前的数量。
猜你喜欢
  • 2020-12-04
  • 2016-01-08
  • 2016-01-31
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 2014-04-27
相关资源
最近更新 更多