为什么免费工作这样?

Par*_*x13 2 c malloc ansi

给出以下代码:

typedef struct Tokens {
    char **data;
    size_t count;
} Tokens;

void freeTokens(Tokens *tokens) {
    int d;
    for(d = 0;d < tokens->count;d++)
        free(tokens->data[d]);
    free(tokens->data);
    free(tokens);
    tokens = NULL;
}
Run Code Online (Sandbox Code Playgroud)

为什么我需要额外的:

free(tokens->data);
Run Code Online (Sandbox Code Playgroud)

不应该在for循环中处理吗?

我已经对valgrind/drmemory进行了测试,实际上顶部循环正确地释放了所有动态内存,但是如果我删除了识别的行,我会泄漏内存.

怎么会?

Pur*_*rag 6

让我们看一下你在程序中使用的内存图:

+---------+       +---------+---------+---------+-----+
| data    |  -->  | char *  | char *  | char *  | ... |
+---------+       +---------+---------+---------+-----+
| count   |            |         |         |
+---------+            v         v         v
                     +---+     +---+     +---+
                     | a |     | b |     | c |
                     +---+     +---+     +---+
                     |...|     |...|     |...|
                     +---+     +---+     +---+
Run Code Online (Sandbox Code Playgroud)

在C中,我们可以为一(更简单地说,一个数组)元素动态分配空间.但是,我们不能使用数组类型来引用该动态分配,而是使用指针类型.在这种情况下,指针只指向动态分配的数组的第一个元素.如果向指针添加1,您将获得指向动态分配数组的第二个元素的指针,添加两个指针以获取指向第二个元素的指针,依此类推.

在C中,括号语法(data[1])是添加和解除引用指针的简写.因此,C中的指针可以像数组一样使用.

在图中,data指向char *动态分配的数组中的第一个,这是在内存中的其他位置.

指向的数组的每个成员data都是一个字符串,它本身是动态分配的(因为元素是char *s).

所以,环路将释放字符串('a...','b...','c...',等等),free(tokens->data)重新分配阵列data点,最后,free(tokens)释放整个struct.