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

A Segmentation Fault occurs when calling free() on a null pointer

我在以下代码中观察到一个非常奇怪的行为。
按原样编译,everythig 按预期工作:输出为 "This is a sample program.".

如果我取消注释所有注释行,我会在第一次调用 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 ;
} 

In theory comments shouldn't change the behaviour, right? What is the problem here?

问题是它不是 NULL 指针,因为它还没有被初始化,所以对 free() 的调用试图在一个随机地址释放:

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

这是undefined behaviour, from free():

The behavior is undefined if ptr does not match a pointer returned earlier by malloc(), calloc(), realloc(), or aligned_alloc().

注释不会改变任何定义明确的代码片段的行为。然而,free-ing an uninitialized pointer is undefined behavior。当编译器看到未定义的行为时,它可以自由地做任何它想做的事情;这是一个段错误还是(更隐蔽地)似乎工作正常。

你的问题的标题是 "A Segmentation Fault occurs when calling free() on a null pointer" 但你并没有试图 free() 一个空指针。第一次调用 free():

char *welcome;
free(welcome);

变量welcome没有定义的值。 C 在创建变量时不会初始化变量。如果你这样做了:

char *welcome = NULL;
free(welcome);

那就没问题了,因为 free() 会忽略 NULL。