5

C ++のプログラミング方法には、次のような段落があります。

一般的なプログラミング手法は、動的メモリを割り当て、そのメモリのアドレスをポインタに割り当て、ポインタを使用してメモリを操作し、メモリが不要になったときに削除してメモリの割り当てを解除することです。メモリ割り当てが成功した後、deleteステートメントが実行される前に例外が発生した場合、メモリリークが発生する可能性があります。C ++標準では、この状況に対処するために、ヘッダーにクラステンプレートunique_ptrが用意されています。

誰かが私に例外が発生し、この投稿のようにメモリがリークするという実際の例を紹介することができますか?

4

5 に答える 5

13

もう少し微妙な例。

動的に割り当てられた2つの配列を保持するクラスの単純な実装を考えてみましょう。

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のデストラクタが呼び出されることが保証されます。

しかし、bad_alloc初期化時にを取得すると、を指すsecondメモリがリークします。first

于 2013-03-12T21:26:27.650 に答える
7
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 ++:コンストラクターが例外をスローする可能性がある場合にリソースを処理する(FAQ17.4への参照]

于 2013-03-12T21:22:29.980 に答える
6
void func()
{
    char *p = new char[10];
    some_function_which_may_throw(p);
    delete [] p;
}

の呼び出しがsome_function_which_may_throw(p)例外をスローした場合、。が指すメモリをリークしますp

于 2013-03-12T21:16:26.327 に答える
3

簡単な例

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

}
于 2013-03-12T21:16:47.607 に答える
1

あまり不自然な例ではありませんが、最近、特定のアロケータオブジェクトでノードを割り当てるときに、コードにこの潜在的なリークが見つかりました。

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));
}

ここでコードをコンパイルする

于 2013-03-12T21:35:47.937 に答える