我为二维数组分配内存,它可以工作......但不正确。当我使用 valgrind 来查看我的数组是否分配和释放得很好时,我发现我在 445 上只释放了 29 个 block 。另一个问题是我的数组有 11 列、20 行,所以我认为有 220 个 block 。 我的结果不正确,不是吗?我该如何修复它?
这是我的代码,提前感谢您的回答。
编辑:我的程序应该与 ncurses 库一起使用。我真的应该删除所有链接到的内容吗?
这次是我所有的代码:
#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
initscr();
noecho();
curs_set(0);
keypad(stdscr, TRUE);
if (init_board() == -1)
return (-1);
while (1)
refresh();
endwin();
return (0);
}
void print_board(int **tab) {
int i;
int line;
i = 0;
printw("------------\n");
while (i < 20) {
line = 11;
printw("| ");
while (line-- > 0) {
tab[i][line] = 0;
if (tab[i][line] == 0)
printw("* ");
}
printw("|\n");
i++;
}
wprintw(stdscr, "------------\n");
}
int **board_size(int **tab) {
int i;
i = 0;
while (i < 20) {
if ((tab[i] = (int *)malloc(sizeof(int) * 11)) == NULL) {
wprintw(stdscr, "%s\n", "Second malloc's tab failed.");
return (NULL);
}
i++;
}
return (tab);
}
void free_board(int **tab) {
int i;
i = 0;
while (i < 20) {
printw("%d\n", i);
free(tab[i]);
i++;
}
free(tab);
}
int init_board() {
int **tab;
tab = NULL;
if ((tab = (int **)malloc(sizeof(int*) * 20)) == NULL) {
wprintw(stdscr, "%s\n", "First malloc's tab failed.");
return (-1);
}
if ((tab = board_size(tab)) == NULL)
return (-1);
print_board(tab);
free_board(tab);
return (0);
}
最佳答案
您的代码没有任何问题,并且您正在释放分配的所有内存。您不能也无法控制的是由curses 库分配的用于管理各种窗口和curses 环境的内存。例如:
valgrind 输出
$ valgrind ./bin/board
==18521== Memcheck, a memory error detector
==18521== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18521== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==18521== Command: ./bin/board
==18521==
==18521==
==18521== HEAP SUMMARY:
==18521== in use at exit: 199,908 bytes in 440 blocks
==18521== total heap usage: 468 allocs, 28 frees, 205,540 bytes allocated
==18521==
==18521== LEAK SUMMARY:
==18521== definitely lost: 0 bytes in 0 blocks
==18521== indirectly lost: 0 bytes in 0 blocks
==18521== possibly lost: 0 bytes in 0 blocks
==18521== still reachable: 199,908 bytes in 440 blocks
==18521== suppressed: 0 bytes in 0 blocks
==18521== Rerun with --leak-check=full to see details of leaked memory
==18521==
==18521== For counts of detected and suppressed errors, rerun with: -v
==18521== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
您正在分配 1040
字节(在 x86_64 上)(960
字节在 x86 上)为您的 220
整数和20
指针。您无法控制剩余的~198,000
由curses库中的例程分配的字节。
所以你并没有发疯,你正在释放你应该释放的东西。当您使用分配内存块的库进行编程时,您应该检查是否有 valgrind
将排除curses分配的模式或排除文件(很像GTK/glib所做的那样)窗口环境预分配大块来处理它们执行的各种任务。当您的代码退出时,该内存将始终显示为仍在使用中。 (在程序最终退出之前,库可能会也可能不会清理)。
但是,正如其他人指出的那样,您不应该强制返回 malloc
。请参阅:Do I cast the result of malloc?进行彻底的解释。您的分配应该更合适,例如:
if ((tab = malloc (sizeof *tab * 20)) == NULL) {
...
if ((tab[i] = malloc (sizeof **tab * 11)) == NULL) {
关于C: 为什么释放 int** 数组没有完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35879726/