看看下面的代码片段。
struct s {
char name[32];
};
void foo(bool x) {
char *n = (char *) "Duke";
if (x) {
s tmp;
strcpy(tmp.name, "Alice");
//Uncomment the following to reveal the magic
//printf("%s\n", tmp.name);
n = tmp.name;
}
printf("%s\n", n);
}
foo(true)在取消注释if块内的 printf 语句和其他一些随机垃圾时,将字符串Alice
打印两次。
可能是什么原因?
编译器信息:
编译器:G ++ 7.3
优化:O3
编辑:被称为“原始”帖子的链接无法回答我的问题,因为提供的链接涉及两个函数之间的交互,而我的问题专门涉及函数内块之间的交互。主要区别在于编译器处理程序堆栈的方式。
答案 0 :(得分:4)
struct s {
char name[32];
};
void foo(bool x)
{
// char *n = (char *) "Duke"; // don't cast away const:
char const *n = "Duke";
if (x) {
s tmp;
strcpy(tmp.name, "Alice");
//Uncomment the following to reveal the magic
//printf("%s\n", tmp.name);
n = tmp.name;
}
printf("%s\n", n); // n points to tmp.name, which is gone now as *)
}
*)它是在块中定义的变量,该块是先前if
语句的受控语句。其生存期以}
结束该块而结束。变量超出范围。在生存期结束后通过指针访问tmp.name
是undefined behaviour。指针不再保存有效的指针值。
还
printf("%s\n", n);
是
的很长的版本puts(n);
不仅通过代码字符,而且还通过运行时开销。
void foo(bool x)
{
char const *n = "Duke";
if (x)
n = "Alice";
puts(n);
}
void foo(bool x)
{
puts(x ? "Alice" : "Duke");
}