代码之家  ›  专栏  ›  技术社区  ›  Kevin Meredith

指针电阻

  •  3
  • Kevin Meredith  · 技术社区  · 15 年前

    如果*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

    谢谢

    6 回复  |  直到 13 年前
        1
  •  7
  •   djna    15 年前

    对。从堆中进行分配在这里是可行的。确保在某个地方再次释放它,否则会泄漏内存。

    通常,智能指针有助于实现这种“不要忘记”逻辑。

        2
  •  3
  •   maksim Tiago    15 年前

    右——堆中的内存(例如,使用malloc分配)将在 get_ii() 的范围。一定要释放它。你也可以分配申报 ii 作为 static int ii ,在这种情况下,其指针将存在于 GETSII() 也是。

        3
  •  3
  •   slacker    15 年前

    您基本上是返回一个不再存在的变量的地址( ii 当函数 get_ii() 开始执行,并且仅在函数退出之前存在)。对内存的任何访问 int *ii 在里面 main() 导致未定义的行为。

    另一方面,堆内存是在显式请求时分配的,在显式请求之前不会释放。因此,如果在函数内部分配一个内存块,将指向该内存块的指针返回给调用者就非常好了。只要确保在不再需要内存块时记录负责释放内存块的人员!

        4
  •  2
  •   Kisalay    15 年前

    代码中的问题将发生,因为当您在main中访问ii时,在get_ii()返回后,通过ii访问的变量已经被破坏。

    如果从get-ii返回在堆上分配的内存,那么在显式销毁之前,内存将是可访问的。

        5
  •  2
  •   Dustin Getz sunsations    15 年前

    更邪恶的是:

    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返回时会被销毁。 通过按值而不是按引用返回来解决此错误,这样可以在str超出作用域之前立即生成它的副本。

        6
  •  0
  •   Zan Lynx    15 年前

    如果您正在编写C样式的代码,那么要做的事情是将指针传入对象,并通过该指针修改对象。这样,get_II函数就不会担心对象来自何处。调用函数负责处理它。

    如果您正在编写C++样式,那么您应该按值返回或返回智能指针或获取引用并通过该引用修改对象。也可以使用C样式并传递指针。一些C++作者更喜欢指针传递,因为它清楚地表明对象正在被修改,而参考通道不清楚。

    现在,如果对象像本例中的对象一样小,那么应该始终按值传递和返回它。它比使用指针更快、更便宜,而且使编码更加简单。