2017-03-14 6 views
2

私はスタック上で基本的なプッシュとポップを行うプログラムに取り組んでいます。私はGDBのプログラムを踏んだことがあり、プログラムはfreeTheMemory関数の5行目に達するまで完全に動作します。プログラムがそこに着くたびに、それは私にコアダンプを与える:私はコア・ダンプを取得していますところそれがなら関数freeTheMemoryでポインタを削除した後にコアダンプが表示されるのはなぜですか?

#include<iostream> 
using namespace std; 

class linkedList{ 
public: 
    int content; 
    linkedList* pointerToBelow; 
}; 

void freeTheMemory(linkedList *above){ 
    if(above!=nullptr){ 
     linkedList* temp; 
     temp=above; 
     above=above->pointerToBelow; 
     delete temp; 
     freeTheMemory(above); 
    } 
} 

void push(linkedList* above, linkedList* below, int x){ 
    below->content=x; 
    above->pointerToBelow=below; 
    below=above; 
    above=new linkedList; 
    return; 
} 

void pop(linkedList* above, linkedList* below){ 
    linkedList* temp; 
    temp=above; 
    above=below; 
    below=below->pointerToBelow; 
    delete temp; 
    return; 
} 

void printList(linkedList *above){ 
    linkedList* temp; 
    temp=above; 
    above=above->pointerToBelow; 
    while(above!=nullptr){ 
     cout<<above->content<<" "; 
     above=above->pointerToBelow; 
    } 
    above=temp; 
} 

int main(){ 
    linkedList *above, *below; 
    int x; 
    above=new linkedList; 
    below=new linkedList; 
    below->pointerToBelow=nullptr; 
    cout<<"Enter the elements of your list: "; 
    while(x!=-9){ 
     cin>>x; 
     if(x!=-9){ 
      if(x>0){ 
       push(above, below, x); 
      } 
      else{ 
       pop(above, below); 
      } 
     } 
    } 
    printList(above); 
    freeTheMemory(above); 
    return 0; 
} 

、問題は私のコードである場合ということですか?もしそうなら、誰がここで何がうまくいかないのか考えていますか?ありがとう

+1

新しい 'linkedList'を作成するときに' pointerToBelow'を初期化することはありません。 – Barmar

+2

あなたは 'push()'にメモリリークを持っています。 'new linkedList'を実行してそれをローカル変数に代入しますが、決して永久的に保存しないでください。 – Barmar

+1

私は彼が従来のCの意味では二重のアスタリスクを使う必要があると思うし、これはC++なので参照(&)演算子を使う必要があると思う。 –

答えて

2

解決策には論理的な欠陥があります。ノードを作成してそのポインタをローカル変数に割り当てるため、リンクされたリストに文字通り追加されないため、実際にはスタックのすべての要素が保持されません。また、2つのポインタを使用するため、コードが不必要に複雑になります。そして、あなたがデバッグするのは難しいです。スタックを実装するためにリンクリストを使用しているので、私は1つのポインタで十分だと主張します。

以下、私はあなたのソリューションを改訂しました。私はtopと呼ばれる単一のポインタを保持しています。ダミーノードはスタックの先頭を指しています。そのpointerToBelowは、スタックの実際のトップ要素を指しています。 push

は、次の手順を実行します。

  1. は、新しいノードを作成し、そのcontentxに設定してください。
  2. は、スタックの前の先頭要素へのpointerToBelowを設定し
  3. は、この新しいノードにpointerToBelowtopのポイントを持っています。 pop

次の手順を実行します。スタックの要素がない場合は、

  1. だけ返し、そうでない場合は
  2. の要素以下の要素にtopポイントのpointerToBelowを取得スタックの上部。
  3. スタックの一番上の要素を削除します。 pointerToBelow

あなたは、必ずしもそれにもかかわらず、再帰を必要としません。しかしそれはOKです。

#include<iostream> 
using namespace std; 

class linkedList{ 

public: 
    int content; 
    linkedList* pointerToBelow; 
}; 

void freeTheMemory(linkedList *top) { 

    if(top != nullptr){ 
    linkedList* temp = top->pointerToBelow; 
    delete top; 
    freeTheMemory(temp); // temp is now the top 
    } 
} 

void push(linkedList* top, int x){ 

    // create new node, assign x 
    linkedList *node = new linkedList; 
    node->content = x; 

    // new node points to top element in the stack 
    node->pointerToBelow = top->pointerToBelow; 

    // top now points to the new node 
    top->pointerToBelow = node; 
} 

void pop(linkedList* top){ 

    linkedList* toDelete = top->pointerToBelow; 

    // case 1: stack is empty 
    if(toDelete == nullptr) 
    return; // do nothing 

    // case 2: deleting top element 
    top->pointerToBelow = toDelete->pointerToBelow; 
    delete toDelete; 
} 

void printList(linkedList *top) { 
    top = top->pointerToBelow; 

    while(top != nullptr) { 
    cout << top->content << " "; 
    top = top->pointerToBelow; 
    } 
} 

int main(){ 

int x; 
linkedList *top = new linkedList; 

top->pointerToBelow = nullptr; // indicates stack is empty 

cout<<"Enter the elements of your list: "; 

while(x != -9) { 
    cin >> x; 

    if(x! =- 9) { 
     if(x>0) 
     push(top, x); 
     else 
     pop(top); 
    } 
    } 

    printList(top); 
    freeTheMemory(top); 

    return 0; 
} 
関連する問題