-3

私はこのセグメンテーション違反に気が狂いそうです。私は単純な 2 パス アセンブラを書いています。オペコード、シンボル テーブル エントリなどを取得するための中間ファイルのストリッピングは正常に機能しています。今のところ、マシン コード バッファをコンソールに出力していますが、何かが原因でセグメンテーション エラーが発生しています。

#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、トラブルメーカーになりました。

4

4 に答える 4

2

m_code_buf初期化されていないか、小さすぎると思います。

于 2013-03-10T12:55:35.047 に答える
1
if(token == NULL) cerr<<"null token error";
a = atoi(token);

の場合、あなたtokenNULLちょうどに渡さNULLatoiます...

于 2013-03-10T12:56:35.723 に答える
1

配列とポインターは同じではありません。

m_code_buf現在、次へのポインターとして定義していcharます。

char *m_code_buf;

それは単なるポインタです。それはどこを指していません。char指しているオブジェクトはありません。実際に有効なcharオブジェクトを指しているように扱い始めることはできません。型が a を指すcharことを示しているからといって、それが自動的に指すわけではありません。

次のように変更すると:

char m_code_buf[256];

これにより、 の配列が得られますchar。文字通り、256charサイズのオブジェクトをメモリに割り当てて使用できるようにします。これを に渡しても問題ありませんsprintf

しかし、m_code_bufここはポインタではありません。ただし、配列の名前は、多くのコンテキストで最初の要素へのポインターに暗黙的に変換されます。そのため、配列の名前をポインターではない場合でも、ポインターのように扱い始めることができます。

于 2013-03-10T13:47:31.287 に答える
0

バッファが取りきれないほど多くの書き込みをしたいという意味かもしれません。他の誰かのメモリに書き込みます (segfault)。

于 2013-03-10T12:53:43.363 に答える