【发布时间】:2017-09-17 03:13:03
【问题描述】:
我最近遇到了一些 C++ 代码,我试图理解为什么输出不是我所期望的。这是有问题的代码:
char fun(char *p)
{
char c = *p;
(*p)++;
return c;
}
int main()
{
char arr[3]={'a', 'b', 'c'};
fun(arr + 1);
std::cout << fun(arr + 1);
return 0;
}
这是我的大脑如何解析代码:
对
fun()的第一次调用将地址传递到arr中存储“b”的位置在
fun()内部,p被取消引用,'b' 被分配给cp再次被取消引用并递增为“c”值'b'从
fun()返回
这一点非常简单。
现在,第二次拨打fun() 时我遇到了麻烦。由于此时p 和c 都超出了范围,我假设对fun() 的第二次调用将产生完全相同的结果——明显的区别是返回值将打印到屏幕而不是比丢弃。但是,结果不是“b”,而是“c”——事实上,对fun(arr + 1) 的额外调用会在每次后续调用中进一步增加返回值到 d、e、f、g、h 等。
我知道即使在指针超出范围后该值仍存储在堆栈中,但我无法弄清楚即使在指针被销毁后该值似乎仍被引用。
【问题讨论】:
-
您每次都将相同的地址传递给
fun,因此每次该地址处的值都会递增,并返回之前的值。 -
你所有的问题都没有实际意义。显示的代码是未定义的行为,
<<运算符可能会由于尝试打印非空终止字符串的内容而导致随机崩溃。 -
@SamVarshavchik 介意指出哪个部分(或行)是 UB?
-
带有
<<运算符的那个。 -
@SamVarshavchik 没有尝试打印任何类型的字符串。 fun 返回单个字符,而不是您误读的 char *,因此应该明确定义,尽管它并没有像 OP 想象的那样。