2013-03-10 77 views
-3

我即將對此分段錯誤感到厭煩。我正在寫一個簡單的2通匯編器。剝離中間文件以獲得操作碼,符號表條目等工作正常。現在我正在將機器代碼緩衝區打印到控制檯,但是有些問題導致了分段錯誤。使用cout進行打印時出現分段錯誤

#include"./assembler.h" 
using namespace std; 

int main(void) 
{ 
ifstream inf("pooltab"); 
int pooltab[10],pooltab_ptr=0; 

while(true) 
{ 
    int x; 
    inf>>x; 
    if(inf.eof()) break; 
    pooltab[pooltab_ptr++] = x; 
} 
for(int i=0;i<pooltab_ptr;i++) 
    cout<<pooltab[i]<<endl; 
pooltab_ptr = 0; 
inf.close(); 

inf.open("intermediate.asm"); 
// ofstream outf("machine_code"); 
    sym_tab symtab; 
literal_tab littab; 

symtab.create_tab(); 
littab.create_tab(); 

char buf[50],*token,*m_code_buf,ch; 
int loc_cntr=0,id,ltrl,a,b; 

while(true) 
{ 
    inf.getline(buf,50); 
    if(inf.eof()) break; 
    token = strtok(buf,"(), "); 
    if(token != NULL) 
    { 
     if(token[0] == 'A' && token[1] == 'D') 
     { 
      token = strtok(NULL,",)"); 
      if(token == NULL) 
      { 
       cerr<<"null token error"; 
       return -1; 
      } 
      id = atoi(token); 
      if(id == 1 || id == 2) 
      { 
       token = strtok(NULL,",() C"); 
            if(token == NULL) 
       { 
        cerr<<"null token error"; 
        return -1; 
       } 
       loc_cntr = atoi(token); 
      } 
     } 

     if(token[0] == 'I' && token[1] == 'S') 
     { 
      token = strtok(NULL,",)"); 
      if(token == NULL) 
      { 
       cerr<<"null token error"; 
       return -1; 
      } 
      id = atoi(token); 
      if(id == 10 || id == 11) 
      { 
       token = strtok(NULL,"S,() "); 
       if(token == NULL) 
       { 
        cerr<<"null token error"; 
        return -1; 
       } 
       a = atoi(token); 
       a = symtab.get_addr(a); 
       sprintf(m_code_buf,"%03d) + %02d 0 %03d\n",loc_cntr,id,a); 
       cout<<m_code_buf; 
      } 
      else if(id == 1) 
      { 
       sprintf(m_code_buf,"%03d) + %02d 0 000\n",loc_cntr,id); 
       printf("%s",m_code_buf); 
      } 
      else if(id > 1 || id < 10) 
      { 
       token = strtok(NULL,"() "); 
       if(token == NULL) 
       { 
        cerr<<"null token error"; 
        return -1; 
       } 
       a = token[0] - 48; 
       token = strtok(NULL," (,"); 
       if(token == NULL) 
       { 
        cerr<<"null token error"; 
        return -1; 
       } 
       ch = token[0]; 
       printf("%d %d %c \n",id,a,ch); 
      } 

      loc_cntr++; 
     } 
    } 
} 
inf.close(); 
// outf.close(); 

return 0; 
} 

這是我檢查在中間代碼文件命令語句(IS,1) (1) (S,1)的方式。錯誤在sprintf。現在,當我修改代碼時,故障似乎從一個地方跳到另一個地方。例如,在一次我使用cout而不是printf。然後sprintf就好了,但是cout產生了錯誤。那麼我改變了生成pooltab的方式,現在sprintf是麻煩製造者。

+0

您可能在某處導致未定義的行爲。向我們展示完整的功能(以及令牌的定義)。 – 2013-03-10 12:55:13

+0

實際代碼太大,但尚未完成,但確定。 – Ajinkya 2013-03-10 13:01:41

+0

char m_code_buf [256];做了一個簡單的改變。非常感謝你們。 – Ajinkya 2013-03-10 13:28:52

回答

0

這可能意味着你想寫更多的緩衝區可以採取。它會讓你在某人的其他記憶上寫(segfault)。

2

我猜m_code_buf要麼沒有初始化,要麼太小。

1
if(token == NULL) cerr<<"null token error"; 
a = atoi(token); 

如果tokenNULL,你剛過NULLatoi ...

+0

好吧,現在所有的錯誤檢查都已到位,但沒有運氣。IS sprintf的ID = 1仍然存在問題。 – Ajinkya 2013-03-10 13:21:42

+0

fredrik有你的答案。 – nneonneo 2013-03-10 13:22:48

1

數組和指針是不一樣的。

目前,您已經定義m_code_buf爲指針char

char *m_code_buf; 

也就是說只是的指針。它沒有指向任何地方。沒有指向的char對象。你不能開始對待它,因爲它實際上指向任何有效的對象。僅僅因爲這個類型告訴你它將指向一個char,並不意味着它會自動執行。

當你將它更改爲:

char m_code_buf[256]; 

這給你的char數組。它實際上在內存中分配256個大小的對象供您使用。這是很好的,通過這個sprintf

但是m_code_buf這裏不是指針。但是,在許多上下文中,數組的名稱會隱式轉換爲指向其第一個元素的指針。這就是爲什麼你可以像處理指針那樣開始處理數組的名稱,即使它不是。