如果* get_ii()返回堆内存而不是堆栈内存,是否会消除此问题?
01 int *get_ii()
02 {
03 int ii; // Local stack variable
04 ii = 2;
05 return ⅈ
06 }
07 main()
08 {
09 int *ii;
10 ii = get_ii(); // After this call the stack is given up by the routine
11 // get_ii() and its values are no longer safe.
12
13 ... Do stuff
14 .. ii may be corrupt by this point.
15 }
来源 - http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html
感谢
答案 0 :(得分:7)
是。从堆中分配可以在这里工作。确保在某处你再次释放它,否则你会泄漏内存。
智能指针经常帮助这种“别忘了”的逻辑。
答案 1 :(得分:3)
正确 - 来自堆的内存(例如,使用malloc分配)将持久于get_ii()
的范围之外。只要确保释放它。您也可以将声明ii
分配为static int ii
,在这种情况下,它的指针也会存在于get_ii()
之外。
答案 2 :(得分:3)
您基本上返回一个不再存在的变量的地址(ii
在函数get_ii()
开始执行时创建,并且仅在函数退出时才存在)。对int *ii
中main()
所指向的内存的任何访问都会导致未定义的行为。
另一方面,堆内存在您明确请求时分配,并且在您明确请求之前不会释放。因此,如果在函数内部分配一个内存块,那么将指向该内存块的指针返回给调用者是完全正常的。只需确保在不再需要时记录谁负责释放内存块!
答案 3 :(得分:2)
您的代码中会出现问题,因为当您在main中访问ii时,在get_ii()返回后,您通过ii访问的变量已被销毁。
如果从get_ii返回通过堆分配的内存,那么内存将被访问,直到它被明确销毁
答案 4 :(得分:2)
std::string& makeString() //returns a reference
{ std::string str = "Dustin"; return str; }
main(){
std::string s = makeString();
//s is a dangling reference! makeString returns a reference to str,
//but str is on the stack and goes out of scope, so we're keeping a reference to nothing
}
str(内部makeString)位于堆栈上,并在makeString返回时被销毁。 通过返回by-value而不是by-reference来解决此错误,这会在str超出范围之前生成str的副本。
答案 5 :(得分:0)
如果您正在编写C风格的代码,那么要做的是传入指向对象的指针并通过该指针修改对象。这样,get_ii函数不会担心对象来自何处。调用函数负责处理它。
如果您正在编写C ++风格,那么您应该按值返回或返回智能指针或获取引用并通过该引用修改对象。或者您可以使用C风格并传递指针。一些C ++作者更喜欢指针传递,因为它清楚地表明在引用传递不明确时正在修改对象。
现在,如果对象在此示例中很小,则应始终传递并按值返回。它比使用指针更快更便宜,它使编码更简单。