【问题标题】:Print function not reading freed values correctly打印功能未正确读取释放的值
【发布时间】:2017-05-28 01:14:36
【问题描述】:

我正在使用搜索树,为了查看树是否结束,我检查它是否为空。 我的问题是当我使用 free() 时,指针值不会变为 NULL

我也尝试过使用指向 free 的指针,然后设置为 NULL,但它不起作用。

在这种情况下,我想删除搜索树上的最大数字,但我的打印函数无法识别释放的值,而是打印 0。

typedef struct nodo {
    int val;
    struct nodo *l, *r;
}   *ABin;

void print (ABin a) {
     if (a != NULL) {
         print (a -> l);
         printf(" %d ",a -> val);
         print (a -> r);
     }
}

ABin remBiggerA (ABin *a) {
    ABin b = (*a), aux = b;
    int i = 0;
    if (b == NULL) i = 1;
    while (i == 0) {
        if (b -> r == NULL) {
            free (b);
            i = 1;
        }
        else b = b -> r;
    }
    (*a) = aux;
    return aux;
}

【问题讨论】:

  • typedef 指针通常是个坏主意。
  • 我已经给出了最好的答案,我可以给出提供的信息,但是如果你将释放的指针设置为 null 并且你的 null 检查仍然没有注册,那么你正在经历一个完全不同的(几乎可以肯定基于逻辑的)问题。是否可以发布一个最低限度的可验证示例?

标签: c memory null free search-tree


【解决方案1】:

在指针上调用free() 后,它不会将指针设置为空,而是使其无效。这意味着进一步访问该指针地址会导致未定义的行为。您根本无法访问或打印已释放内存中的信息。但是,您可以释放一个指针,然后自己立即将其设置为 null - 这是一件非常有效的事情。如果您已经这样做并且仍然存在问题,那么我怀疑您的问题出在其他地方。

【讨论】:

    【解决方案2】:

    这是预期的行为。您可以在 The GNU C Library 上找到有关 free() 函数的文档。

    释放块会改变块的内容。释放后不要期望在块中找到任何数据(例如指向块链中下一个块的指针)。

    正如 Hiko 所说,在调用 free() 之后将指针分配给 NULL 是一个很好的做法。

    所以,

    free (b);
    b = NULL;
    

    会解决你的问题。


    编辑: 根据 cmets 中 @Seb 的建议,还要检查 The POSIX manual for free()

    【讨论】:

    • 我建议人们参考 POSIX (opengroup) 手册,而不是 GNU 手册;前者往往更准确且符合标准,不太强调扩展The POSIX manual for free can be found here。尽管如此,将 OP 指向手册是个好主意!
    • 也许您应该像为 glibc 文档一样添加手动链接中的“指针的任何使用”文本,以防页面将来移动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多