我在以下代码中观察到一种非常奇怪的行为 按原样编译,everythig按预期工作:输出为"这是一个示例程序。"。
如果我取消注释所有注释行,我在第一次调用free()时会出现分段错误。
理论上,评论不应该改变行为,对吧?这有什么问题?
PS:我在Arch Linux上使用gcc(GCC)4.9.2 20141224(预发布)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char *welcome;
// int max;
// int x;
free(welcome);
welcome = strdup("This will be discarded.");
free(welcome);
welcome = strdup("This is a sample program.\n");
printf ("%s\n", welcome);
// max = 80;
// x = 1;
// while ( x <= max ) {
// int y;
// y = 1 ;
// while ( y <= x ) {
// printf ( "#" ) ;
// y = y + 1 ;
// }
// printf ( "\n" ) ;
// x = x + 1 ;
// }
return 1 ;
}
答案 0 :(得分:6)
理论上,评论不应该改变行为,对吧?这有什么问题?
问题是它不是NULL
指针,因为它尚未初始化,因此对free()
的调用试图在随机地址解除分配:
char *welcome;
// int max;
// int x;
free(welcome);
如果ptr与之前由malloc(),calloc(),realloc()或aligned_alloc()返回的指针不匹配,则行为未定义。
答案 1 :(得分:5)
注释不会更改任何明确定义的代码段的行为。但是,free
-ing an uninitialized pointer is undefined behavior。当编译器看到未定义的行为时,它可以自由地做任何想做的事情;无论是段错还是(更加隐蔽)似乎都能正常工作。
答案 2 :(得分:3)
你的问题的标题是“在空指针上调用free()时发生了分段错误”,但你并没有试图释放()一个空指针。你第一次打电话给free():
char *welcome;
free(welcome);
变量welcome
没有定义的值。 C不会在创建变量时初始化变量。如果你这样做了:
char *welcome = NULL;
free(welcome);
然后它会没问题,因为free()会忽略NULL。