请参阅以下代码段。在第二个函数中,我将返回一个引用。我在函数中声明一个局部变量并返回地址。由于变量是局部的,我相信它的生命在退出函数时结束。我的问题是,为什么即使原始变量被删除,也可以在没有任何异常的情况下从调用者访问值?
int& b=funcMulRef(20,3);
int* a= funcMul(20,3);
int* funcMul(int x,int y)
{
int* MulRes = new int;
*MulRes = (x*y);
return MulRes;
}
int& funcMulRef(int x,int y)
{
int MulRes ;
MulRes = (x*y);
return MulRes;
}
此致 约翰
答案 0 :(得分:7)
第二个函数的行为只是 undefined ;任何事情都可能发生,并且在许多情况下,它似乎会起作用,因为没有任何东西覆盖过去将结果存储在堆栈中的位置。
答案 1 :(得分:2)
您正在访问不再在范围内的数据。
内存可能仍然包含数据,但它似乎可以正常工作,但很可能在任何时候重复使用,并且值将被覆盖。
下次调用任何函数或分配本地堆栈变量时,很可能会为新数据重用该内存并覆盖之前的内容。这是不完美的行为。
答案 2 :(得分:2)
不会删除原始值。仅仅因为删除它的动作会导致一些看不见的计算。
该值仍然存在,但内存空间不再是您的,实际上是未定义的。
您指向内存中可能被程序覆盖的空间。
答案 3 :(得分:2)
不,你不应该这样做。访问堆栈上的残留数据的结果是不确定的。除此之外,如果您的返回值是类类型,则它的析构函数将被调用。
你想避免临时物品吗?如果是这样,您可能会对此感兴趣:
http://en.wikipedia.org/wiki/Return_value_optimization
答案 4 :(得分:0)
在这些情况下,它很可能无效:
funcMulRef(10,3) + funcMulRef(100,500)
或者,以更恶劣的方式:
std::cout << "10*3=" << funcMulRef(10,3) << " 100*500=" << funcMulRef(100,500) << std::endl;
如果你使用-Wall ,gcc会警告这种错误