我有以下代码:
char* p;
void func1()
{
p = "hello world";
}
int main()
{
func1();
printf(p);
return 0;
}
此代码在这里工作正常,但我想知道它是否正确或是否存在"未定义的行为"这里。
" hello world"仍然存在于func1()之外?
答案 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$
(*注意:据我所知,它可能是实现定义的,但是)