开发者

pointer resistance

If *get_ii() returned heap memory, rather than stack memory, would this problem be eliminated?

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 }  

Source - http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

thanks


Yes. Allocating from the heap would work here. Make sure that somewhere you release it again otherwise you'll leak memory.

Often smart-pointers help with this kind of "don't forget" logic.


Right -- memory from the heap (allocated with malloc, for example) will be persistent outside of get_ii()'s scope. Just make sure to free it. You could also allocate declare ii as static int ii, in which case its pointer would exist outside outside of get_ii(), too.


You are basically returning the address of a variable which no longer exists (ii is created when the function get_ii() starts executing, and exists only until the function exits). Any access to the memory pointed by int *ii in main() causes undefined behavior.

On the other hand, heap memory is allocated when you explicitly request it, and is not released until you explicitly request it. So if you allocate a memory block inside a function, it is perfectly fine to return the pointer to that memory block to the caller. Just make sure to document who is responsible for freeing the memory block when it is no longer needed!


The problem in your code will occur because when you access ii in main, after get_ii() returns, your variable accessed through ii is already destroyed.

If you return a memory allocated over heap from get_ii, then the memory will be accessible till it is explicitly destroyed


even more nefarious:

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 (inside makeString) is on the stack and is destroyed when makeString returns. resolve this error by returning by-value instead of by-reference, which makes a copy of the str right before it goes out of scope.


If you are writing C-style code, the thing to do is to pass in a pointer to an object and modify the object via that pointer. That way the get_ii function does not worry about where the object came from. The calling function takes care of it.

If you are writing C++-style, then you should return by value or return a smart pointer or take a reference and modify the object via that reference. Or you can use the C-style and pass a pointer. Some C++ authors prefer the pointer pass because it makes it clear that the object is being modified while a reference pass is not clear.

Now, if the object is small as it is in this example, you should always pass and return it by value. It is faster and cheaper than using a pointer and it makes the coding more simple.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜