C: 为什么释放 int** 数组没有完成?

标签 c arrays

我为二维数组分配内存,它可以工作......但不正确。当我使用 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/

相关文章:

c - 优化函数进入/退出 (gcc)

将 16 字节 IPv6 转换为冒号分隔的字符串

c++ - address of operator 可以初始化一个指针但是填充的值是垃圾

php - 如何在 smarty 模板中访问数组的键和值?

arrays - 矩阵中的累积和

arrays - 更新旧代码,什么是 Array(_unsafeUninitializedCapacity : 1024,initializingWith: 0)

c - 有可用的 mbed 以太网接口(interface)库吗?

c - 如何使用 XCode 以 C 语言输出笑脸

arrays - nodejs 如何使用多维数组并在其中推送值?

python - 如何在文本文件中从打印 [1, 2, 3] 到打印 1, 2, 3 Python