2010-11-27 11 views
5

operator newが動作していますが、削除を呼び出すとすぐにfree (ptr)行でクラッシュします。この基本クラスでnew演算子をオーバーロードして削除すると、間違っていることを誰にでも伝えることができますか?ヒント:私は設計上の問題については問いません。演算子の削除によりヒープの破損が発生しました。演算子newが正常に動作しています

class Base { 
private: 
    int i; 

public: 
    Base() : i (10) { 
    } 

    static void * operator new (size_t size) { 
     if (size = 0) size = 1; // please read this line carefully! size = 0! 
     return malloc (size); 
    } 

    static void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 
+1

あなたは二回、オブジェクトを削除するか、 'new'を呼び出してから取得していないポインタを経由してオブジェクトを削除しようとしていますか? –

+0

補足として、 'free(NULL)'は安全であることが保証されているので、特別なケースは必要ありません。 –

+0

hm ...私の悪い: 'if(size == 0)'を 'if(size = 0)'に置き換えて、コンストラクタだけでなくプライベートデータメンバを追加すると、コードは失敗します。私は 'size = 0'は発生してはならないバグですが、コンストラクタでこのクラスのプライベートデータメンバを初期化するときにのみコードが失敗することを知っています。 – Jaywalker

答えて

4

これが私の作品:

#include <cstdlib> 
using namespace std; 
class Base { 
public: 
    void * operator new(size_t size) { 
     if (size == 0) size = 1; 
     return malloc (size); 
    } 

    void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 

int main() 
{ 
    Base* b = new Base; 
    delete b; 
    return 0; 
} 

[email protected]:/tmp$ g++ -o test test.cpp 
[email protected]:/tmp$ ./test 
[email protected]:/tmp$ valgrind ./test 
==7229== HEAP SUMMARY: 
==7229==  in use at exit: 0 bytes in 0 blocks 
==7229== total heap usage: 1 allocs, 1 frees, 1 bytes allocated 
==7229== 
==7229== All heap blocks were freed -- no leaks are possible 
==7229== 
==7229== For counts of detected and suppressed errors, rerun with: -v 
==7229== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 
+0

ありがとうございます。はい、コードは問題ありません。私は自分のコードでいくつかの変更を加えました。あなたはそれについてコメントできますか? – Jaywalker

1

私はあなたが与えているサンプルコードに問題が表示されません。

以下は私にとってうまくいきます。

[email protected] ~ $ cat leak_check.cpp && g++ leak_check.cpp && valgrind --leak-check=full ./a.out 
#include <cstdlib> 
class Base { 
public: 
    static void * operator new (size_t size) { 
     if (size == 0) size = 1; 
     return malloc (size); 
    } 

    static void operator delete (void *ptr, size_t size) { 
     if (ptr == NULL) return; 
     free (ptr); 
    } 
}; 

int main() 
{ 
    Base * p = (Base *) Base::operator new(sizeof(Base)); 
    Base::operator delete((void*)p,sizeof(Base)); 
} 
==4561== Memcheck, a memory error detector 
==4561== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==4561== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
==4561== Command: ./a.out 
==4561== 
==4561== 
==4561== HEAP SUMMARY: 
==4561==  in use at exit: 0 bytes in 0 blocks 
==4561== total heap usage: 1 allocs, 1 frees, 1 bytes allocated 
==4561== 
==4561== All heap blocks were freed -- no leaks are possible 
==4561== 
==4561== For counts of detected and suppressed errors, rerun with: -v 
==4561== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6) 

nullポインタは完全に正常です。

free関数は、空間を割り当て解除するptrによって指さ、つまり、さらに割当てのために利用可能にさせます。 ptrがヌルポインタの場合、は何も起こりません

したがってif (ptr == NULL) return;を省略することができます。

2

実際の問題はnewdeleteの演算子ではありません。それらの実装はかなり簡単ですが、ここに問題はありません。

実際の問題はヒープ破損です。あなたのコードによって引き起こされたもので、必ずしもBaseのオブジェクトを操作するコードとは限りません。 あなたのオブジェクトがdeleteのときにヒープの破損が正確に発見されただけです。

おそらく、deleteのオブジェクトの直前にヒープの破損を行うコードがあります。

無効なメモリアクセスのコードを確認する必要があります。これには含まれています:あなたはそれを解放した後、あなたがメモリを使用していないことを確認し

  • 割り当てられたより多くのメモリにアクセスしないの確保

    1. を。
    2. など