2017-04-05 8 views
1

アセンブラとして機能するプログラムをビルドしようとしていますが、コマンドライン引数としてファイル名を取得してマシンコードに変換します。Ubuntuでセグメンテーションフォールト(コアダンプ)エラーが発生する

プログラムはうまくコンパイルされ、1つのファイル名でOKが実行されますが、複数で実行しようとすると、最初の繰り返しの後にエラーが表示されます。

Clear()関数(以前の繰り返しで割り当てられたすべてのデータを消去します)があるかもしれませんが、その理由はわかりません。これは部分的ですが、私が言ったように、いくつかのファイルが使用されていなければプログラムは実行されます。

struct symbolStruct { // a structure which is used to absorb info about a tag, its place in memory and related flags 
    char *name; 
    int place; 
    unsigned int isEntry : 1; 
    unsigned int isData : 1; 
    unsigned int isExternal : 1; 
    struct symbolStruct *next; 
}; 

typedef struct { // a structure which is used to absorb info about the operand structure of an instruction line 
    unsigned int numOfOperands : 2; 
    unsigned int addrMethSou : 2; 
    unsigned int addrMethDest : 2; 
    unsigned int operation : 4; 
    unsigned int extraWords : 2; 
    char *firstOperand; 
    char *secondOperand; 
} OperandType; 

typedef struct { 
    unsigned int row : WORD_SIZE; 
} int15; 

struct MachineCode { // a structure which is used to absorb machine code lines, and their location in the assembly file 
    unsigned int row : WORD_SIZE; 
    unsigned int line; 
    OperandType *structure; 
    struct MachineCode *next; 
}; 

struct DataCode { // a structure which is used to absorb data and string elements (signed numbers and ascii characters) 
    unsigned int row : WORD_SIZE; 
    struct DataCode *next; 
}; 

struct Operation { /* the main operation structure, contains pointers to all used lists, the ic and dc counters, the 
    current line number which is dealt with and the error flag. */ 
    unsigned int ic; 
    unsigned int dc; 
    struct symbolStruct *externHead; // a pointer to a linked list of extern tags used in the assembly file, and their locations 
    struct symbolStruct *symbolHead; // a pointer to a linked list of all tags 
    struct DataCode *dataHead; // a pointer to a linked list of all data/string elements 
    struct MachineCode *machineHead; // a pointer to a linked list of all machine code rows 
    int linenumber; 
    unsigned int errorflag : 1; // raised in case of an error which triggered a warning 
}; 

#include "header.h" 

void FirstRun(struct Operation*, char *); 
void DataUpdate(struct symbolStruct*,int); 
void SecondRun(struct Operation *, char *); 
void Clear(struct Operation *); 

int main(int argc, char *argv[]) { 
    int i; 
    struct Operation programCore = {0,0,NULL,NULL,NULL,NULL,0,0}; 
    for(i=1;i<argc;i++) { 
     char *fn = argv[i]; 
     FirstRun(&programCore,fn); 
     DataUpdate(programCore.symbolHead,programCore.ic+INSTRUCTION_OFFSET); 
     SecondRun(&programCore,fn); 
     Clear(&programCore); 
     programCore.symbolHead = programCore.externHead = programCore.dataHead = programCore.machineHead = NULL; 
    } 
    if(argc < 2) { 
     fprintf(stderr,"No files selected.\n"); 
    } 
    return 0; 
} 

/*Used to empty the linked lists and allocated memory after the program has finished one iteration. */ 
void Clear(struct Operation *programCore) { 
    /*f(pointer name) is there to hold a pointer to the allocated memory which is about to be flushed. */ 
    struct MachineCode *machineHead = programCore->machineHead, *fMachineHead; 
    struct DataCode *dataHead = programCore->dataHead, *fDataHead; 
     struct symbolStruct *externHead = programCore->externHead, *fExternHead; 
    struct symbolStruct *symbolHead = programCore->symbolHead, *fSymbolHead; 
    while(machineHead != NULL) { 
      fMachineHead = machineHead; 
     machineHead = machineHead->next; 
     if(fMachineHead->structure != NULL) { 
      if(fMachineHead->structure->numOfOperands == 2) 
       free(fMachineHead->structure->secondOperand); 
      if(fMachineHead->structure->numOfOperands > 0) 
       free(fMachineHead->structure->firstOperand); 
      free(fMachineHead->structure); 
     } 
     free(fMachineHead); 
    } 
    while(dataHead != NULL) { 
     fDataHead = dataHead; 
     dataHead = dataHead->next; 
     free(fDataHead); 
    } 
    while(externHead != NULL) { 
     fExternHead = externHead; 
     externHead = externHead->next; 
     free(fExternHead->name); 
     free(fExternHead); 
    } 
    while(symbolHead != NULL) { 
     fSymbolHead = symbolHead; 
     symbolHead = symbolHead->next; 
     free(fSymbolHead->name); 
     free(fSymbolHead); 
    } 
    programCore->ic = programCore->dc = programCore->linenumber = programCore->errorflag = 0; 
} 
+2

あなたのコードがクラッシュする場所は言わずに、デバッガで実行すると、どの行になるのかがわかります。また、修正する必要があるものも表示される場合があります。 –

+1

[オフトピック]個人的には、(可変サイズの)配列を使用し、テーブルのリンクリストは使用しません。 – wildplasser

+0

は、1)空白行を使用してコードブロック(for、else、while、do ... while、switch、case、default)を区切ります。 2)関数を2行または3行の空白行で区切ります(一貫性を保つ)3)公理に従う:* 1行につき1つの文と1文につき1つの変数宣言* – user3629249

答えて

0

コンテキスト構造体(programCore)でリンクリストを解放して無効にしないでください。私はあなたがメモリブロックを解放するポインタを使用していると思われる。

この行だけをコピーポインタ:

struct MachineCode *machineHead = programCore->machineHead; 

しばらく()ループが頭の上に直接実行、それを修正するにはprogramCore->machineHead

をクリアされていません。

while(programCore->machineHead != NULL) 
{ 
    ... 
} 
+0

私はそうするでしょうが、それだけではなく、頭だけをクリアするのではなく、リスト全体がクリアされていることを確認します頭が無効になっていますか? –

+0

firstOperandとsecondOperandの両方の文字列がクリアされていることを確認します。 –

+0

私はこのプログラムは実際に私が頭を無効にしていないという事実であると思います。後で私はhead == NULLかどうかをチェックし、新しいノードにメモリを割り当てる関数を持っています。 –

0

まあ、取り除くことによって

if(fMachineHead->structure->numOfOperands == 2) 
     free(fMachineHead->structure->secondOperand); 
    if(fMachineHead->structure->numOfOperands > 0) 
     free(fMachineHead->structure->firstOperand); 

私は、エラーを解決するために管理しているが、今、私は新しいものになっています - 次の行を参照する

main.c:242:13: error: request for member ‘symbolHead’ in something not a structure or union 
main.c:242:38: error: request for member ‘externHead’ in something not a structure or union 
main.c:243:13: error: request for member ‘dataHead’ in something not a structure or union 
main.c:244:13: error: request for member ‘machineHead’ in something not a structure or union 

-

 programCore.symbolHead = programCore.externHead = programCore.dataHead = programCore.machineHead = NULL; 

、私はそれを書いた方法に問題はありますか? (明らかにはい、しかし私はそれを見ない)。

+0

これらのフィールドは 'unsigned int'であり、いくつかは' int'であり、演算は右から左に行われるため、 'unsigned int'値は' int'値から割り当てられます。それぞれの課題を別のステートメントとして書くことを提案する。 – user3629249

+0

問題は 'protramCore'はポインタなので、'。 'ではなく ' - 'を使用する必要があります。また、それぞれのポインタは異なる型であり、操作は右から左に行われます。割り当てられる。それぞれの課題を別のステートメントとして書くことを提案する。 – user3629249

0

clear()関数をもう一度変更しましたが、今は正常に動作しているようです。

/*Used to empty the linked lists and allocated memory after the program has finished one iteration. */ 
void Clear(struct Operation *programCore) { 
    /*f(pointer name) is there to hold a pointer to the allocated memory which is about to be flushed. */ 
    struct MachineCode *machineRowPointer = programCore->machineHead, *fMachineRow; 
    struct DataCode *dataRowPointer = programCore->dataHead, *fDataRow; 
     struct symbolStruct *externSymbolPointer = programCore->externHead, *fExtern; 
    struct symbolStruct *symbolPointer = programCore->symbolHead, *fSymbol; 
    if(machineRowPointer != NULL) { 
     while(machineRowPointer != NULL) { 
      if(machineRowPointer->structure != NULL) 
       free(machineRowPointer->structure); 
      fMachineRow = machineRowPointer; 
      machineRowPointer = machineRowPointer->next; 
      free(fMachineRow); 
     } 
     programCore->machineHead = NULL; 
    } 
    if(dataRowPointer != NULL) { 
     while(dataRowPointer != NULL) { 
      fDataRow = dataRowPointer; 
      dataRowPointer = dataRowPointer->next; 
      free(fDataRow); 
     } 
     programCore->dataHead = NULL; 
    } 
    if(externSymbolPointer != NULL) { 
     while(externSymbolPointer != NULL) { 
      fExtern = externSymbolPointer; 
      externSymbolPointer = externSymbolPointer->next; 
      free(fExtern->name); 
      free(fExtern); 
     } 
     programCore->externHead = NULL; 
    } 
    if(symbolPointer != NULL) { 
     while(symbolPointer != NULL) { 
      fSymbol = symbolPointer; 
      symbolPointer = symbolPointer->next; 
      free(fSymbol->name); 
      free(fSymbol); 
     } 
     programCore->symbolHead = NULL; 
    } 
    programCore->ic = programCore->dc = programCore->linenumber = programCore->errorflag = 0; 
} 
関連する問題