全局字符指针指向函数内定义的常量字符串

时间:2014-05-21 19:36:44

标签: c

我有以下代码:

char* p;


void func1()
{
    p = "hello world";
}

int main()
{
    func1();

    printf(p);

    return 0;
}

此代码在这里工作正常,但我想知道它是否正确或是否存在"未定义的行为"这里。

" hello world"仍然存在于func1()之外?

2 个答案:

答案 0 :(得分:4)

字符串文字是具有静态存储持续时间的字符数组(参见C11 6.4.5 / 6),因此它们的生命周期延伸到整个程序的末尾。你的代码很好。

答案 1 :(得分:3)

答案是肯定的 - “你好世界”仍然存在于func1()之外。

那是因为字符串文字实际上并没有存储在func1的堆栈中,而是(通常)存储在这种文字的全局表中。

然而,有两点说明:

1)即使对于常量str,执行printf(str)也是不好的做法 - 如果字符串碰巧包含'%'字符,那么它将被解释为格式的一部分{{1}将最终读出界限,你会得到未定义的行为。例如:

printf

重要的部分是char* str = "100% string!"; ... printf(str); 部分 - printf会将其解释为格式字符串的一部分,并期望其参数中包含另一个字符串;因为你没有提供一个,它最终会试图取消引用任意内存,你会得到未定义的行为。

你可以做的是调用printf,如下所示:

% s

这是安全的,因为只有第一个参数被解释为格式字符串。

2)你在其他地方有一个微妙的未定义行为(*请注意下面) - 即,C标准要求你的输出以换行符结束(printf("%s", str); ) - 它不必与你的主字符串在同一个printf调用中,但它必须最终

所以这些都很好:

\n

但这不是:

printf("hello, world");
printf("\n"); // can also just be "hello world\n"
//<program exit>

在实践中,实现没有问题,但是当程序没有输出最终换行符时,用户会很烦,因为终端会在程序完成后打印自己的东西({{ 1}}这里是shell提示符:

printf("hello, world");
//<program exit>

VS。没有新行:

user$

(*注意:据我所知,它可能是实现定义的,但是)