2017-04-26 2 views
0

C++で基本的なリンクリストを作成していますが、シグナル11(これはValgrindを使用して見つかりました)でプログラムを実行すると何らかの理由でデストラクタがsegfaultになります。 My Linkオブジェクトには2つの変数しかありません。 string valueLink* next単純なLinkedListプログラムのデストラクタsegfault

これはデストラクタです。

​​

これはmain.cppに

int main() { 

    string temp; 
    getline(cin, temp); 
    Link* head = new Link(temp, NULL); 
    Link* tempHead = head; 

    for(int i = 1; i < 5; i++) { 
    getline(cin, temp); 
    Link* newLink = new Link(temp, head); 
    head = newLink; 
    } 
    head->printAll(head); 
    head->~Link(); 

    return 0; 

} 

EDITです:link.cppについては 、私はthis-

Link::~Link() { 
    Link* curr = this; 
    delete curr; 
} 

をしました。そしてmain.cppにするために、私は

head->~Link()を変更しました
Link* curr = tempHead; 
    while(curr!=NULL) { 
    Link* nextLink = curr->getNext(); 
    curr->~Link(); //replacing with delete curr gives the same segfault 
    curr = nextLink; 
    } 
+1

1: 'head->〜Link();'これをしないでください。 2: 'delete curr;'あなたはデストラクタの中から 'this'を削除しています。 – tkausl

+0

それではどうしたらいいですか?私はかなり新しいC++です – Kek

+1

明示的にデストラクタを呼び出すことは、通常正しいパスではありません。 –

答えて

2

デストラクタでdelete curr;を実行すると、そのノードのデストラクタが再度呼び出され、無限の再帰的ループがスタックをオーバーフローする可能性があります。

デストラクタで効果的に「これを削除してください」と呼ばれるべきではありません。

代わりに考えてみます。

Link::~Link() { 
     delete next; 
} 

そしてメインで、単にこれは長いリストと小さなスタックと問題になることができ、まだ再帰的であるdelete head;

を使用しています。代わりに、デストラクタではなくリストを歩くメイン関数にループを置くこともできます。クラス自体にdeleteループをカプセル化する場合は、ループを実行する明確なメソッドを追加します。デストラクタから呼び出さないでください。

+1

)解決策は' main() 'で' delete head; 'delete nullptr;'は安全です(https://stackoverflow.com/questions/4190703/is-it-safe-to-delete-a-null-ポインタ)。 –

関連する問題