2016-12-10 6 views
0

新しいポインタの配列を宣言します。 私の質問です:delete[]でアレイを削除すると、プログラムがクラッシュするのはなぜですか?サンプルコード:なぜこのテストプログラムは破棄されますか

#include <iostream> 

using namespace std; 

typedef unsigned int uint32; 

struct demon{ 
    private: 
    static uint32 next_id; 
    public: 
    uint32 id; 
    demon(){ 
     id = demon::next_id; 
     demon::next_id++; 
    } 
}; 

uint32 demon::next_id = 1; 

int main(){ 
    demon** demons = new demon*[5]; 
    demon d1; 
    demon d2; 
    demon d3; 
    demon d4; 
    demon d5; 

    demons[1] = &d1; 
    demons[2] = &d2; 
    demons[3] = &d3; 
    demons[4] = &d4; 
    demons[5] = &d5; 

    cout << demons[1]->id << endl; 
    cout << demons[2]->id << endl; 
    cout << demons[3]->id << endl; 
    cout << demons[4]->id << endl; 
    cout << demons[5]->id << endl; 

    delete[] demons; // without this, the code works 
    return 0; 
} 
*** Error in `./test': free(): invalid next size (fast): 0x0000000000e68c20 *** 
Aborted 

私は削除せずに、同様のメモリリークのためにそれをテストし、プログラムがセグメンテーションフォールトます。

+1

http://stackoverflow.com/a/41078565/719662は間違っています(実際には答えはありません)。誰かがあなたにそれを与えるので最初の答えを受け入れないでください... SOの多くの答えはまったく間違っています。 – vaxquis

+0

実際には、あなたの問題は他の場所にあります:https://en.wikipedia.org/wiki/Off-by-one_error – vaxquis

+1

tl;あなたは適切に割り振りと割り当てを解除しています。 'demons [5]'にインデックスを付けた結果、heisenbugになります - インデックスを適切な0..4の範囲( 'demons [0]' ... 'demons [4]')にシフトすると、あなたのコードは動作します正しく。 – vaxquis

答えて

2

In C++ containers (arrays/vectors) use zero-based numbering.あなたは使用する必要があります。

demons[0] = &d1; 
demons[1] = &d2; 
demons[2] = &d3; 
demons[3] = &d4; 
demons[4] = &d5; 

を、それが今であるので、あなたが割り当てられていないメモリ領域に書き込みをしています。これは非常に複雑なエラーシナリオの一般的な原因です。したがって、valgrindに精通している必要があります。

+1

私はあなたにそれを言わなかった、ジョナス、しかしあなたはまだ完全に正しいです、これは実際のエラーです:http://ideone.com/mhBqSU – vaxquis

+1

@vaxquis面白いことに、私は 'demons [5]'私のオフラインテストでは 'demons [0]'に:-)良い編集(リンクを追加)。 – Jonas

+0

私はそれに気づきました。その単純な間違いを発見してくれてありがとう。 –

関連する問題