在 C 中释放结构后奇怪的断言失败 [重复]

Weird assert failure after a struct free in C [duplicate]

提问人:bongadonga 提问时间:6/27/2023 最后编辑:bongadonga 更新时间:6/27/2023 访问量:40

问:

我是 C 语言的初学者,我遇到了这个奇怪的失败:assert

假设我们有这个设置:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

typedef struct {
    int id;
} Struct;

Struct* new_struct(int id) {
    Struct* s;
    if ((s = malloc(sizeof(Struct))) == NULL) {
        return NULL;
    }
    s->id = id;
    return s;
}

void free_struct(Struct* s) {
    if (!s) {
        return;
    }
    free(s);
    s = NULL;
    assert(s == NULL); // no problem here, `s` is NULL.
}

int main(void) {
    Struct* s = new_struct(4);
    printf("%d\n", s->id);
    
    free_struct(s);
    assert(s == NULL); // Causes assert failure.
    
    return EXIT_SUCCESS;
}

为什么函数内部失败,但函数最后一行的函数通过?assert(s == NULL)mainfree_struct()

我试图调试正在发生的事情,但没有结果。

编辑: 我添加了该函数,但这不是导致这种奇怪的断言失败的原因,它仍然会发生。return s;new_struct()

c 指针 null assert free

评论


答:

0赞 chux - Reinstate Monica #1

assert(s == NULL); // Causes assert failure.

代码没有改变,因为调用不会影响这里的值。main()sfree_struct(s);s

0赞 ikegami 6/27/2023 #2

首先,你忘记了 ,所以你的程序的行为是不确定的。(始终启用编译器的警告!return s;new_struct

但即使在修复此问题后,您也会看到相同的行为。那是因为不修改 的 .参数是按值传递的,这意味着 's 完全独立于 's 。你更改了 的 ,但不是 的 。free_struct(s)mainsfree_structsmainsfree_structsmains

您可以使用以下方法:

#define free_struct(s) { free(s); s = NULL; }

(无需检查是否是。sNULL