2012-03-13 19 views
2

このコードを実行するとSegfaultが発生します。理由はわかりません。特定の行(以下に示す)をコメントアウトするとsegfaultが削除され、イテレータ "i"の再帰的使用が問題を引き起こしている可能性があると考えられましたが、それをポインタに変更してもセグメンテーションが発生します。Segfault in recursive function

void executeCommands(string inputstream, linklist<linklist<transform> > trsMetastack) 
{ 
int * i=new int; 
(*i) = 0; 
while((*i)<inputstream.length()) 
{ 
    string command = getCommand((*i),inputstream); 
    string cmd = getArguments(command,0); 
    //cout << getArguments(command,0) << " " << endl; 


    if (cmd=="translate") 
    { 

     transform trs; 
     trs.type=1; 
     trs.arguments[0]=getValue(getArguments(command,2)); 
     trs.arguments[1]=getValue(getArguments(command,3)); 
     ((trsMetastack.top)->value).push(trs); 
     executeCommands(getArguments(command,1),trsMetastack); 
    } 

    if (cmd=="group") 
    { 
     //make a NEW TRANSFORMS STACK, set CURRENT stack to that one 
     linklist<transform> transformStack; 
     trsMetastack.push(transformStack); 


     //cout << "|" << getAllArguments(command) << "|" << endl; 
     executeCommands(getAllArguments(command),trsMetastack); // COMMENTING THIS LINE OUT removes the segfault 

    } 

    if (cmd=="line") 
    { //POP transforms off of the whole stack/metastack conglomeration and apply them. 


     while ((trsMetastack.isEmpty())==0) 
     { 
      while ((((trsMetastack.top)->value).isEmpty())==0) //this pops a single _stack_ in the metastack 
      { transform tBA = ((trsMetastack.top)->value).pop(); 
       cout << tBA.type << tBA.arguments[0] << tBA.arguments[1]; 
      } 
      trsMetastack.pop(); 
     } 


    } 

は「Metastackは」私は再帰中に関数に送信する必要がリンクリストのリンクリストである、そのように宣言 :

linklist<transform> transformStack; 
    linklist<linklist<transform> > trsMetastack; 
    trsMetastack.push(transformStack); 


    executeCommands(stdinstring,trsMetastack); 

「Getallarguments」機能は、単に抽出するためのものです

string getAllArguments(string expr) // Gets the whole string of arguments 
    { 
     expr = expr.replace(0,1," "); 
     int space = expr.find_first_of(" ",1); 
     return expr.substr(space+1,expr.length()-space-1); 
    } 

リンクリストクラスの定義は次のとおりです。

template <class dataclass> 
    struct linkm { 
     dataclass value;  //transform object, point object, string... you name it 
     linkm *next; 
    }; 

    template <class dataclass> 
    class linklist 
    { 
    public: 
     linklist() 
     {top = NULL;} 
     ~linklist() 
     {} 
     void push(dataclass num) 
     { 
      cout << "pushed"; 
      linkm<dataclass> *temp = new linkm<dataclass>; 
      temp->value = num; 
      temp->next = top; 
      top = temp; 
     } 
     dataclass pop() 
     { 

      cout << "pop"<< endl; 
      //if (top == NULL) {return dataclass obj;} 
      linkm<dataclass> * temp; 
      temp = top; 
      dataclass value; 
      value = temp->value; 
      top = temp->next; 
      delete temp; 
      return value; 
     } 
     bool isEmpty() 
     { 
      if (top == NULL) 
      return 1; 
      return 0; 
     } 
     // private: 
     linkm<dataclass> *top; 
    }; 

お読みいただきありがとうございます。私は問題が漠然としていることを知っていますが、最後の1時間をgdbでデバッグしようとしています。正直なところ、何ができるのか分かりません。

+3

segfaultを取得する理由がわからない場合は、gdbでプログラムを実行するか、生成されたコアダンプを使用してください。 –

+0

私はそれを試しました。 gdbはトップが空であると言ったが、それ以外は私にメモリアドレスを与えていた。 :/ – xyzzy

+0

[ここで 'i'にポインタを使用しないでください](https://twitter.com/#!/klmr/status/177173159836008448)。まずこれを修正してください。 –

答えて

1

これは何でもかまいませんが、私の野生の推測は皮肉なことですが、スタックオーバーフローです。 あなたは

void executeCommands(string &inputstream, linklist<linklist<transform> > &trsMetastack) 

:例えば、参照として周りにあなたのデータ構造を渡ししようとする場合があります。しかしヴラドが指摘したように、あなたはGDBに慣れるしたい場合があります。

+0

ああ、私はまだ物事を参考にして渡すのは良くない。これらを両方の&リファレンスに変更した後、私はいくつかのエラーが発生しました。それらを修正しようとしました、ダイスはありません。左辺値を取得するときに何かが値を必要としましたが、関数の仕組みを変更しようとしましたが、それは乱雑です。私はその後、上記のポインタを変更しようとし、ポインタを処理するために他のすべてを変更した後、私のコードはまったく出力されませんでした。 :( – xyzzy