【问题标题】:using free() in C using a for loop使用 for 循环在 C 中使用 free()
【发布时间】:2013-02-20 06:24:01
【问题描述】:

我正在为我的班级用 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);
}

如果 ^ 这个 ^ 崩溃了,我正在考虑这样做:

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;
};

【问题讨论】:

  • 这是一个非常糟糕的主意:typedef struct node *node;。现在struct nodenode 都是名称类型,但它们命名不同的类型。埃加兹!
  • 未定义的行为不会导致崩溃。访问已释放的指针会导致未定义的行为。
  • 问题很可能隐藏在typedef struct node *node中。第一个 sn-p 显然是错误的,因为它在 free(curr) 之后取消引用 curr
  • 释放内存时,“free”函数不会重置指针。我们必须在释放内存后显式初始化指针为 NULL。

标签: c memory free


【解决方案1】:

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

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

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

【讨论】:

  • 提醒他内容可能保留之后 free()有什么意义?他应该在free()之前取消引用它
  • @phoeagon 它解释了观察到的行为
  • 答案没有提到未定义的行为。它应该。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多