C++ 在C+中,有没有什么方法可以防止内存泄漏而不要求开发人员额外注意它+;

C++ 在C+中,有没有什么方法可以防止内存泄漏而不要求开发人员额外注意它+;,c++,memory-leaks,C++,Memory Leaks,目前,我们有几种防止内存泄漏的方法,例如 代理(共享ptr、自动ptr)和 簿记方法 垃圾收集(java) 但是前者需要开发人员提供大量的开销,而后者则会导致大量的资源开销 有没有其他方法可以节省资源并使开发人员免于此问题 有没有办法防止内存泄漏,而不要求开发者在C++中格外注意?p> 使用最小的动态分配,仅在严格必要时生效 如果您使用的是动态分配,那么您必须遵守它附带的价格,这就是正确处理它。最好的方法是在C++中使用 ,注意编写RAII代码不是微不足道的,但通过实践,人们习惯于以Raii方式

目前,我们有几种防止内存泄漏的方法,例如

  • 代理(共享ptr、自动ptr)和
  • 簿记方法
  • 垃圾收集(java)
  • 但是前者需要开发人员提供大量的开销,而后者则会导致大量的资源开销

    有没有其他方法可以节省资源并使开发人员免于此问题

    有没有办法防止内存泄漏,而不要求开发者在C++中格外注意?p> 使用最小的动态分配,仅在严格必要时生效


    如果您使用的是动态分配,那么您必须遵守它附带的价格,这就是正确处理它。最好的方法是在C++中使用<强> <强>,注意编写RAII代码不是微不足道的,但通过实践,人们习惯于以Raii方式思考。

    < P>良好的编码实践成为良好的编程“强>习惯< /强>,然后,很少需要注意”以利用它们。我建议使用RAII包装器对象,如std::unique_ptr、std::shared_ptr,以及关于何时何地应使用动态分配的明确指导原则。
    一个很好的起点是,如果您看到有人键入单词
    delete
    ,那么它应该是一个标志,您需要格外小心

    这就引出了我的第二点:不要使用动态分配(除非绝对必要),尽量使用自动销毁的范围控制对象。永远不要
    new
    RAII对象,这将迫使您考虑如果范围发生变化,RAII所有者包装的对象应该如何处理

    例如:

    std::auto_ptr<Foo> ptr2Foo( new Foo() );
    ...
    ...
    if(ptr2Foo->isValidNow())
        passToOwningObject(otherObject, ptr2Foo);
    //now when scope ends the newed Foo will be destroyed or owned
    //by an appropriate object.
    
    class DataWrapper
    {
    public:
        const BYTE* PeekAtData() const;        
        BYTE* RemoveData();
    ....
    };
    
    std::auto_ptr ptr2Foo(new Foo()); ... ... 如果(ptr2Foo->isValidNow()) passToOwningObject(其他对象,ptr2Foo); //现在,当范围结束时,新的Foo将被销毁或拥有 //通过适当的对象。 或

    std::unique_ptr ptr2Foo(new Foo());
    ...
    ...
    如果(ptr2Foo->isValidNow())
    passToOwningObject(其他对象,std::move(ptr2Foo));
    //现在,当范围结束时,新的Foo将被销毁或拥有
    //通过适当的对象。
    

    并定期运行代码分析(MSVC、Valgrind、Coverity等),不要忽略编译器警告。

    我一直觉得使用引用、按引用返回和传递以及尽可能精确的常量正确性可以解决大部分问题。您无法删除引用,因此不希望您删除。您无法删除常量指针,因此不需要删除。然后,在极少数情况下,编码器会收到一个非常量指针,他们会注意到

    真正关注堆分配对象的所有权概念,如果有的话,不情愿地揭示/公开它们

    此外,编写更完整的接口以提供线索,例如:

    std::auto_ptr<Foo> ptr2Foo( new Foo() );
    ...
    ...
    if(ptr2Foo->isValidNow())
        passToOwningObject(otherObject, ptr2Foo);
    //now when scope ends the newed Foo will be destroyed or owned
    //by an appropriate object.
    
    class DataWrapper
    {
    public:
        const BYTE* PeekAtData() const;        
        BYTE* RemoveData();
    ....
    };
    

    如果有一个一刀切的解决方案,不需要任何价格,你不认为它会在每一个初学C++的书中被广告吗?@ PrimaHa:RAII当然应该在每一个初学者的书中被广告。可悲的是,我怀疑很多人教得不够早。堆栈变量。不能漏。你必须为此努力。见1中关于RAII的备注。代理,列表中的第一个应该是
    unique\u ptr
    。它比
    shared\ptr
    更容易(正确)使用
    auto_ptr
    是禁用的关键字;)。Java垃圾收集不能防止所有内存泄漏。您仍然可以轻松地将对象保留在全局集合中,这些对象将永远不会被释放。这仍然是内存泄漏,尽管不是指针丢失。+1表示“只在严格必要时使用最小的动态分配”,我不同意一点:编写RAII很简单。至少与C++中管理内存的其他东西相比。我特别想到了通过ref-to-const以外的任何东西传递
    shared_ptr
    的陷阱。请记住,使用作用域出口类实用程序,您可以轻松地进行作用域绑定资源管理(SBRM,RAII的更好名称),因此您甚至不需要编写很多小的实用程序类。@GMan:实际上,有人向我指出,SBRM与RAII略有不同,因为RAII还容纳离开作用域的变量(例如,
    func(std::map&m)
    :)@GMan:SBRM似乎暗示变量的生存期绑定到特定的作用域(
    scoped\ptr
    是一个很好的例子)。但是,使用
    shared_ptr
    unique_ptr
    分配的资源可能不会绑定到特定的范围。您可以完全删除指向const的指针,请参见。我应该说“搞乱”,这实际上偏离了主题。但我所看到的很多代码都把所有东西都当作裸指针扔掉了,内存泄漏/损坏也源于一些同样的坏习惯!该死,我生气了……:)您需要
    std::move
    a
    unique\u ptr
    来传递其所有权。@Xeo-opps。我还没有使用它们(在VC9中)。。。汽车是我实际使用的,所以我改成了汽车。