C:为什么释放int **数组不完整?

时间:2016-03-08 22:58:11

标签: c arrays

我为我的2D阵列分配内存,它可以工作......但不正确。当我使用valgrind看看我是否分配并释放我的数组时,我看到我在445上只释放了29个集团。另一个问题是我的阵列有20列的11列,所以我认为220个集团。 我的结果不正确,不是吗?我该如何解决?

有我的代码,请提前感谢您的答案。

编辑:我的程序应该与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);
}

2 个答案:

答案 0 :(得分:2)

您的代码没有任何问题,您可以释放所分配的所有内存。您不能控制的是 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整数和960指针分配220个字节(在x86_64上)(x86上为20个字节)。您无法控制curses库中例程分配的剩余~198,000字节。

所以你不会发疯,你正在释放你应该做的事情。使用分配内存块的库进行编程时,应检查是否存在将排除curses分配的valgrind模式或排除文件(非常类似于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) {

答案 1 :(得分:0)

这个答案不正确。我没有意识到指针数组是在一个例程中分配的,而整数数组是在其他例程中分配的。

  

您在board_sizeinitialize_board中{{1}}。以前没有分配指针数组。看起来很奇怪。

context ends up in the result一样,尝试首先删除无关的所有内容。某些库可能会在初始化时分配内存,并且在程序终止之前不会释放它。

顺便说一下,分配n * m一次数组比分配n + 1数组更容易,更有效。