释放在块中间声明的C指针(有关此问题,请参阅文档)

Freeing C pointers declared in the middle of a block (seeking documentation on this)

在哪里记录了这种行为(如果有的话)?

当您在块中间的C中声明一个指针时,它可能处于错误状态(指向不可用的内存),并且您不能使用标准的if (a) free(a)来释放它。

我想到的最简单的程序是

1
2
3
4
5
6
7
8
#include <stdlib.h>
int main(int argc, char *argv[]){
    if(argc > 1) goto END;
    char *a = NULL;
    a = calloc(1,1);
END:
    if(a) free(a);
}

运行不带参数的程序,它可以正常运行,如果使用至少一个参数运行它,则它可能会中断如下:
令我惊讶的是,如果使用clang进行编译,它可能会起作用(在我的OS X上可以,但是在NetBSD上则不能)。 如果您使用gcc,它将始终返回

1
malloc: *** error for object 0x7fff5fc01052: pointer being freed was not allocated

注意,该程序的声明位于该块的开头是正确的。

编辑:请注意,问题是关于文档。 我意识到做我描述的事情是不安全的,但是我没有发现明确显示它的地方。


"模式"

1
if(a) free(a);

当然不是标准的,或者至少不是。 将NULL传递给free()是安全的,因此if不添加任何内容。

如果您跳过初始化,我希望a的值是不确定的(不太可能是NULL),这对我来说很有意义。 这确实是冗长的代码,请不要这样做。

可能会争辩说,goto和标签的存在意味着未实现范围,并且完全没有理由free(a);语句位于标签之后(在a的"不可见"范围之外) 被定义为)。