1

我正在为我的班级用 C 语言编写一个程序,并且我正在做结对编程。我想知道它是如何不使程序崩溃的。我的伙伴在下面添加了这段代码,我运行 valgrind 来测试是否有任何内存泄漏,这似乎很好 - 再说一次,我是新手。无论如何,我想知道这段代码是如何工作的,因为当我释放 curr 时,接下来运行的是 curr = curr->link - 但我们只是释放了 curr!那么 curr 被取出内存怎么会有链接呢?我以为这样的事情是行不通的。

这是我的伙伴写的:

for(node curr = list->head; curr != NULL; curr = curr->link ){
   if (!dflag) printf("%s\n",curr->words);
   else printf("[%p]\n",curr);
   free(curr->words);
   free(curr);
}

如果 ^ this ^ 崩溃,这是我想做的事情:

for (node curr = list->head; curr != NULL; ) {
   if (!dflag) printf("%s\n",curr->words);
   else printf("[%p]\n",curr);
   node prev = curr;
   curr = curr->link;
   free(prev);
}

此外,这是我们制作节点的方式:

typedef struct node *node;

struct node {
   cstring words;
   node link;
};
4

2 回答 2

2

仅仅因为你释放了内存并不意味着它的内容已经丢失。您的内容可能会保留一段时间,直到内存返回给另一个调用者malloc()并且调用者写入它。

显然你不能也不应该依赖这个。valgrind应该打印出与访问已释放内存有关的错误。

这是我们的老朋友“未定义行为”的一个例子。虽然我们可以解释为什么它可能会以某种方式运行,但不能保证会发生这种情况,并且根据定义依赖它是一个错误。出于这个原因,当这些事情崩溃时,你实际上会更幸运,因为这些事情很可能在你最意想不到的时候被忽视并导致各种奇怪的问题。

于 2013-02-20T06:29:41.593 回答
0

您需要使用-gflag 进行编译以获得有用的 valgrind 输出。第一个代码是错误的,因为您无法对释放的数据做出任何假设。定义自指针的正常方法是这样的:

struct node {
   cstring words;
   struct node *link;
};
于 2013-02-20T06:31:47.053 回答