2017-04-05 173 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

[off-topic]個人而言,我會使用(可變大小)數組,而不是表的鏈接列表。 – wildplasser

+0

爲便於閱讀和理解:1)通過一個空白行分隔代碼塊(用於,如果,其他,同時,同時,切換,大小寫,默認)。 2)用2或3個空白行分開函數(保持一致)3)遵循以下公理:*每行只有一條語句和(最多)一條語句的變量聲明* – user3629249

回答

0

您不釋放和取消上下文結構中的鏈接列表(programCore)。我懷疑你正在使用指針釋放內存塊。

此行只複製指針:

struct MachineCode *machineHead = programCore->machineHead; 

的while()循環是不清除programCore->machineHead

爲了解決這個問題,直接在頭上運行:

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

如果我會這麼做,是不是隻清除了頭,而不是之後的節點是如何確保整個列表被清除,並且頭部無效? –

+0

我也想確保清除了firstOperand和secondOperand所指的字符串。 –

+0

我認爲這個程序確實是這樣的一個事實,即我不是無效的頭,因爲後來我有一個函數檢查頭== 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

又變清()函數,它似乎是現在的工作很好。

/*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; 
}