2017-07-27 9 views
0

cellという名前のクラスを作成しました。このクラスの中にはcellポインタの配列があります。ヘッダーは次のようになります。C++でポインタの配列を削除するとデストラクタがクラッシュする

class cell 
{  
public: 
    cell(); 
    cell *c[8]; 
    void creatcells(); 
    virtual ~cell(); 
    .. 

} 

cppファイルには、次のようになります。

cell::cell() 
{ 
//ctor 
for(int i=0;i<8;i++) 
{ 
    c[i]=NULL; 
} 

} 


void cell::creatcells() 

{ 
    cell c1,c2,c3,c4,c5,c6,c7,c8; 

    c[0]=&c1; 
    c[1]=&c2; 
    c[2]=&c3; 
    c[3]=&c4; 
    c[4]=&c5; 
    c[5]=&c6; 
    c[6]=&c7; 
    c[7]=&c8; 
} 

cell::~cell() 
{ 
    for(int i=0; i<8; i++) 
    { 
     if (c[i]!=NULL) 
     { 
        delete c[i]; 
     } 
    } 
    delete[] c; 

} 

しかし、プログラムが終了するたびに、それがなぜ、クラッシュ?
私はif (c[i]!=NULL)なしで試しましたが、これは役に立ちません。 forループがなければ、コードは完全に終了しますが、これも削除する必要があることを私は知っています。 デストラクタを正しく書いたと思いますか?

+0

デバッガを使用したプログラムを開くと、クラッシュポイント – user5821508

+3

'セルc1、c2、c3、c4、c5、c6、c7、c8; '< - これらのすべてがメソッドの最後にスコープ外にあり、アドレスは無効です。 – crashmstr

+2

変数 'c1'、' c2'などは、関数 'createcells'の範囲外に存在しません。したがって、それらへのポインタを格納することは、あなたにぶら下がっているポインタの配列を持たせることになります。 – CoryKramer

答えて

5
void cell::creatcells() 
{ 
    cell c1,c2,c3,c4,c5,c6,c7,c8; 

    c[0]=&c1; 
    c[1]=&c2; 
    ... 

上記cellオブジェクトのすべてが自動的にデストラクタでcreatecells()。だからdelete c[i];の終わりに破壊されているが、あなたがしたいUB.Whatある

c[0]= new cell(); 
c[1]= new cell(); 
+3

あなたが本当に望むのは 'std :: vector 'と戻り値の最適化です! – Bathsheba

+0

そうすることで、前と同じように削除する必要がありますか?またはそれらは破壊されていますか?私はあなたが提案したコードを変更し、以前のようにデストラクタを保持しましたが、再びクラッシュします... –

+0

@NoamChai 'delete [] c;'ループ内のすべてのオブジェクトを既に削除しているので、これは不要です。 –

4

自動保存期間があり、もはや有効範囲にない変数deleteへのポインタを逆参照しようとしています。あなたのコンパイラはこれについてあなたに警告しませんでしたか?

したがって、プログラムの動作はで、定義されていないのはです。

あなただけこれまでペアnew[]delete[]newdeletedelete(さらにはnew )をstd::unique_ptrのような管理されたポインタクラスに委任できます。

std::vector<cell>にリファクタリングして戻り値の最適化を使用するのはなぜですか? std::make_uniqueを使用して


+0

... 'new'を' std :: make_unique'に委譲してください。 –

+0

@MartinBonner:ありがとうございます。 – Bathsheba

3

機能cell::createcellsで変数がローカルですされており、スコープの外に出て、関数が復帰すると破壊されます。これらのオブジェクトは、削除しようとすると存在しません。これらのポインタを参照解除するとundefined behaviorになります。

deleteあなただけがnewであることは言うまでもありません。あなたはnew何もしていないので、のポインタにdeleteがあります。undefined behaviorにつながります。

シンプルなソリューションを使用することですvectorオブジェクトの:

std::vector<cell> c; 

そして、単にベクトルに8つのcellオブジェクトを追加します。ベクトルが含まれています今

void cell::creatcells() 
{ 
    c = std::vector<cell>(8); 
} 

8デフォルトで構築cellオブジェクト。コンストラクタやデストラクタで何もする必要はありません。実際にはこれを使って、コンストラクタとデストラクタをthe rule of zeroに従って完全に削除することをお勧めします。

関連する問題