我正在尝试构建一个可以用作汇编程序的程序,它将获取文件名作为命令行参数并将它们转换为机器代码。
该程序编译得很好,使用 1 个文件名运行正常,但是当我尝试使用多个文件名运行时,第一次迭代后会出现错误。
我认为 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;
}
您不会释放和取消上下文结构 ( programCore
( 中的链表。我怀疑您正在使用指向释放内存块的指针。
此行仅复制指针:
struct MachineCode *machineHead = programCore->machineHead;
while(( 循环未清除programCore->machineHead
要修复它,请直接在头部运行:
while(programCore->machineHead != NULL)
{
...
}
好吧,通过摆脱
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;
我写的方式有问题吗?(显然是的,但我只是没有看到它(。
再次更改了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;
}