在空指针上调用free()时发生分段错误

时间:2015-01-22 21:55:30

标签: c gcc free sigsegv

我在以下代码中观察到一种非常奇怪的行为 按原样编译,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 ;
} 

3 个答案:

答案 0 :(得分:6)

  

理论上,评论不应该改变行为,对吧?这有什么问题?

问题是它不是NULL指针,因为它尚未初始化,因此对free()的调用试图在随机地址解除分配:

char *welcome;
//        int max;
//        int x;
free(welcome);

来自undefined behaviourfree()

  

如果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。