C ++中的内存泄漏示例(通过使用异常)[重复]

Posted

技术标签:

【中文标题】C ++中的内存泄漏示例(通过使用异常)[重复]【英文标题】:Example of memory leak in c++ (by use of exceptions) [duplicate] 【发布时间】:2013-02-28 14:47:22 【问题描述】:

在 C++ How to program 中有一段说:

一个常见的编程实践是分配动态内存,分配地址 该内存指向一个指针,使用指针来操作内存并释放 当不再需要内存时删除内存。如果之后发生异常 内存分配成功,但在 delete 语句执行之前,内存泄漏 可能发生。 C++ 标准在标头中提供类模板 unique_ptr 以 处理这种情况。

任何人都可以向我介绍一个发生异常并且内存将泄漏的真实示例like this post?

【问题讨论】:

我认为有些人需要重新评估他们对“不是真正的问题”的解释...... 3 个不同的接近投票。也许我应该投第四个(不同的)。 :P 这能回答你的问题吗? How to create a memory leak in C++? 【参考方案1】:

一个更微妙的例子。

简单地实现一个包含两个动态分配数组的类:

struct Foo 
private:
    int* first;
    int* second;
public:
    Foo()
        : first(new int[10000])
        , second(new int[10000])
     

    void Bar()  throw 42; 

    ~Foo()
    
        delete [] first;
        delete [] second;
    
;

int main()

    Foo f;
    /* more code */

现在,如果我们因为在某处调用方法 Bar 而遇到异常,那么一切都很好 - 堆栈展开保证 f 的析构函数被调用。

但是如果我们在初始化second时得到bad_alloc,我们就会泄漏first指向的内存。

【讨论】:

这是一个非常好的例子,我想很多人都搞错了:(【参考方案2】:
class MyClass

public:
    char* buffer;
    MyClass(bool throwException)
    
        buffer = new char[1024];
        if(throwException)
            throw std::runtime_error("MyClass::MyClass() failed");
    

    ~MyClass()
    
        delete[] buffer;
    
;

int main()

    // Memory leak, if an exception is thrown before a delete
    MyClass* ptr = new MyClass(false);
    throw std::runtime_error("<any error>");
    delete ptr;


int main()

    // Memory leak due to a missing call to MyClass()::~MyClass()
    // in case MyClass()::MyClass() throws an exception.
    MyClass instance = MyClass(true);

另请参阅:C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4]

【讨论】:

-1。如果构造函数抛出异常,MyClass* ptr = new MyClass(true); 不会泄漏。 嘿,删除了 -1,但现在最后一个示例中的 newdelete 具有误导性。还有newmalloc在同一个程序里? 不再是:)。感谢您的投票和评论! @Sam:不,我的意思是最后一个样本很可能是int main() MyClass A;,并且内存泄漏仍然会发生。泄漏在 MyClass 中,而不是在那个函数中。 创建正确的内存泄漏示例实际上比预期的要难 xD【参考方案3】:
void func()

    char *p = new char[10];
    some_function_which_may_throw(p);
    delete [] p;

如果对some_function_which_may_throw(p) 的调用引发异常,我们会泄漏p 指向的内存。

【讨论】:

您应该改名为 func real_example。毕竟,OP确实要求提供一个真实的例子;) 那么,这与堆栈展开无关吧?堆栈展开只与堆栈变量有关?【参考方案4】:

简单示例

try  
  int* pValue = new int();
  if (someCondition)  
    throw 42;
  
  delete pValue;
 catch (int&)  


【讨论】:

【参考方案5】:

举一个不那么做作的例子,我最近在使用给定分配器对象分配节点时在我的代码中发现了这种潜在的泄漏。

std::unique_ptr<node,alloc_aware> allocate_new_node(allocator& al, const value_type^ v) 
    char* buffer = al.allocate(sizeof(node)); //allocate memory
    return std::unique_ptr<node>(al.construct(buffer, v),al)); //construct

由于缓冲区的原因,如何解决这个问题不太明显,但在帮助下我得到了它:

struct only_deallocate 
    allocator* a;    
    size_type s;
    only_deallocate(allocator& alloc, size_type size):a(&alloc), s(size) 
    template<class T> void operator()(T* ptr) a->deallocate(ptr, s);
    operator alloc_aware() const return alloc_aware(*a, s);
;

std::unique_ptr<node,alloc_aware> allocate_new_node(allocator& al, const value_type& v) 
    std::unique_ptr<node, only_deallocate> buf(alloc.allocate(sizeof(node)),alloc, sizeof(node));//allocate memory
    alloc.construct(buf.get(), value);
    return std::unique_ptr<node,alloc_aware>(std::move(buf));

Compiling Code here

【讨论】:

以上是关于C ++中的内存泄漏示例(通过使用异常)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用Memory-Analyzer分析内存泄漏

Tensorflow.js 中的内存泄漏:如何清理未使用的张量?

c ++ dll中的内存泄漏[重复]

在合理的时间范围内检测到一定程度内存泄漏的工具

如何用 Valgrind 检测使用 LuaJIT FFI 过程中的内存泄漏

如何在使用 JNI 的 C++/Java 项目中使用 CRT 中的工具检测内存泄漏?