2012-03-13 7 views
2

이 코드를 실행할 때 segfault가 발생하고 이유가 확실하지 않습니다. 특정 라인 (아래에 표시)을 주석 처리하면 segfault가 제거되어 iterator "i"를 재귀 적으로 사용하면 문제가 발생할 수 있다고 생각하게되었지만 포인터로 변경 한 후에도 segfault가 발생합니다.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; 
    }; 

시간을내어 읽어 주셔서 감사합니다. 나는 그 문제가 모호하다는 것을 알고 있지만 gdb로 이것을 디버깅하려고 지난 시간을 보냈다. 솔직히 그것이 무엇인지 모르겠다.

+3

segfault를 얻는 이유를 모르는 경우 gdb에서 프로그램을 실행하거나 생성 된 코어 덤프를 사용하십시오. –

+0

시도해 보았습니다. gdb는 top *이 비어 있다고했지만, 메모리 주소를주고 있다는 것 외에는 전혀 경험하지 못했습니다. :/ – xyzzy

+0

[여기에 'i'에 대한 포인터를 사용하지 마시오.] (https://twitter.com/#!/klmr/status/177173159836008448). 먼저 수정하십시오. –

답변

1

그것은 아무것도 될 수는 없지만 제 아이러니하게도 스택 오버플로입니다. 당신은 :, 참조로 주위에 당신의 데이터 구조를 전달하려고

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

을 예컨대을 할 수 있습니다하지만 블라드가 지적한 것처럼, 당신은 GDB에 익숙해 할 수 있습니다.

+0

아, 아직 일을 잘하고있어. 이들을 양쪽 참조로 변경 한 후에, 나는 약간의 오류가있다. 그것들을 고치려고했는데, 주사위는 없었어. lvalue를 얻었을 때 rvalue가 필요한 것이 었습니다. 함수의 작동 방식을 변경하려고 시도했습니다 ... 더러워졌습니다. 다음 포인터를 위의 변경 시도하고 포인터를 처리하는 다른 모든 변경 한 후 내 코드를 전혀 출력하지 것입니다. :( – xyzzy