2017-05-16 14 views
4

私はnew演算子をオーバーロードするため、このサンプルコードを持っており、このコードは、実際に働いていると、すべてが正しいように思わ過負荷演算子[]削除/削除新/新しい[]グローバルC++

#include <iostream> 
#include <cstddef> 
#include <new> 

#ifdef USE_ZMALLOC 
extern "C" { 
#include "zmalloc.h" 
} 
#define m_malloc zmalloc 
#define m_free zfree 
#else 
#ifdef USE_JEMALLOC 
#include <jemalloc/jemalloc.h> 
#define m_malloc je_malloc 
#define m_free je_free 
#else 
#include "malloc.h" 
#define m_malloc std::malloc 
#define m_free std::free 
#endif 
#endif 

// C++ requires that operator new return a legitimate pointer 
// even when zero bytes are requested. That's why if (size == 0) size = 1 
void* operator new (std::size_t size) throw (std::bad_alloc) { 
    using namespace std; 
    if (size == 0) { // Handle 0-byte requests by treating them as 1-byte requests 
    size = 1; 
    } 

    while (true) { 
    void* mem = m_malloc(size); 

    if (mem != nullptr) { 
     return mem; 
    } 

    new_handler global_handler = set_new_handler(nullptr); 
    set_new_handler(global_handler); 

    if (global_handler) { 
     (*global_handler)(); 
    } else { 
     throw bad_alloc(); 
    } 

    } 
} 

void* operator new[] (std::size_t size) throw (std::bad_alloc) { 
    return operator new(size); 
} 

void operator delete (void* ptr) throw() { 
    if (ptr == nullptr) { 
    return; 
    } 

    m_free(ptr); 
} 

void operator delete[] (void* ptr) throw() { 
    operator delete(ptr); 
} 

を削除します。 私の質問は次のとおりです。

int main() { 
    Foo** foo = new Foo*[10]; 

    std::cout << "# " << zmalloc_used_memory() << "." << std::endl; 

    delete foo; // Using wrong delete operator 

    return 0; 
} 

valgrindのは間違っているオペレータが削除使用して文句はありません:私はこのような何かをすれば、valgrindの使用している場合。 デフォルト演算子のnew/deleteペアを使用すると、valgrindは演算子の削除エラーについて警告します。

1)新しい/削除演算子に問題がありますか?
2)valgrindはこの種のエラーをもう警告していませんか?

Thx!

+0

オペレータnew []が配列の要素のすべてのコンストラクタを呼び出し、delete []の要素デストラクタに対してoperator []がどのように呼び出すのか分かりません。何か不足していますか? –

+0

この例では、配列を作成しました。私は配列内の要素を初期化していません – rcmgleite

+0

@RichardCrittenこれはどのように動作するのですか?演算子newとコンストラクタが呼び出される "新しい式"があります。 –

答えて

0

まず、これらは過負荷ではありません(まったく同じプロトタイプを持つため)。これらは置き換えられます。

おそらく問題は、Valgrindがこれらのグローバル演算子を置き換えたことを知らないということです。共有ライブラリで置き換えを行うと、Valgrindは関数とプロトタイプを見て、それらをフックすることができます。ただし、置き換えが実行ファイル自体にある場合は、Valgrindに伝える必要があります。私は、これはコードをインスツルメントすることによって可能だと思いますが、それはかなり難しいです。より簡単な方法は、Valgrindオプション--soname-synonyms = somalloc = NONEを使用することです。

関連する問題