我在学习指南上发现了这个问题,我不知道为什么返回指向局部变量/参数的指针会很糟糕。有什么想法吗?
发布于 2013-11-19 05:09:18
与其说这是一种“不良实践”(暗示它可能导致问题),不如说它是一种绝对会导致未定义行为的实践。这就像取消引用一个空指针:不要这样做,并期望您的程序在逻辑范围内运行。
解释:
当一个局部变量(包括一个参数)被声明时,就会给它自动存储,这意味着编译器负责为变量分配内存,然后在程序员不做任何努力的情况下释放该内存。
void foo(int bar)
{
int baz;
} //baz and bar dissappear here当变量的生存期结束时(例如,函数返回时),编译器将履行其承诺,函数的所有本地自动变量都将被销毁。这意味着,指向这些变量的任何指针现在指向程序认为“空闲”的垃圾内存。
当返回一个值时,这并不是一个问题:程序找到了一个新的位置来放置这个值。
int foo(int bar)
{
int baz = 6;
return baz + bar; //baz + bar copied to new memory location outside of foo
} //baz and bar disapear当您返回指针时,指针的值将按常规复制。但是,指针仍然指向当前为垃圾的相同位置。
int* foo(int bar)
{
int baz = 6;
baz += bar;
return &baz; //(&baz) copied to new memory location outside of foo
} //baz and bar disapear! &baz is now garbage memory!访问此内存是一种未定义的行为,因此您的程序几乎肯定会以某种方式出现错误行为。例如,我曾经使用过fell victim to this exact problem,虽然我的程序没有崩溃或终止,但当编译器覆盖“空闲”内存时,我的变量开始退化为垃圾值。
发布于 2013-11-19 05:08:19
一旦函数返回,堆栈上的局部变量和参数就会被取消分配。它们可能仍然存在,但是没有保证,当某些东西决定使用堆栈时,它们肯定会被摧毁。
使用WP中的图表:

顶部的堆栈指针可以安全地分配和放置新变量(例如调用函数时)。但是,当函数(例如DrawLine)返回时,它们将从堆栈中取出(堆栈指针只是递增,因此不再指向范围外的、绿色的变量)。以后出现的、分配和使用堆栈空间的任何内容都会破坏旧值。
发布于 2013-11-19 05:07:11
因为它会导致程序中未定义的行为。
https://stackoverflow.com/questions/20063617
复制相似问题