C中的链表给出了分段错误



我一直致力于在C for linux中实现命令行提示符。基本上,它使用系统调用来执行命令。到目前为止,所有这些都有效,但下一部分是实现历史记录命令,所以我通常会使用链表命令。

我知道链表的概念,我知道它们,但我对C没有希望。我似乎无法将我小小的豌豆脑包裹在它周围。因此,每个节点结构都将包含命令(这是一个字符串数组(,然后是指向下一个节点的指针。

我哪里错了?

节点结构定义

struct Node {
char** storedCommand;
struct Node* next;
};

Global Head definition

struct Node* head = NULL;

其他方法

struct Node* createNode(char** command) {
struct Node* returnNode = malloc(sizeof(struct Node));
returnNode->storedCommand = command;
returnNode->next = NULL;
return returnNode;
}
void addNode(char** command) {
struct Node* tempNode = createNode(command);
if(head == NULL) {
head = malloc(sizeof(struct Node));
head = tempNode;
} else {
struct Node* pointerNode = head;
while(pointerNode->next != NULL) {
pointerNode = pointerNode->next;
}
pointerNode->next = tempNode;
}
}
void traverseList() {
struct Node* p = (struct Node*)malloc(sizeof(struct Node));
p = head;
printf("%s", head->storedCommand[0]); // This line fails but why; I thought I have already defined head
while(p != NULL) {
printf("%s", p->storedCommand[0]);
p = p->next;
}
}

所以我评论了它的错误之处,但我真的不知道为什么。

这是我的主要

int main() {
while(TRUE) {
printPrompt();
cmdLine = readCommandLine();
cmd = parseCommandLine(cmdLine);
if(strcmp(cmd[0], "history") != 0) {
addNode(cmd);
}
if(isInternalCommand(cmd)) {
executeInternalCommand(cmd);
} else {
pid = fork();
if(pid == 0) {
executeCommand(cmd);
} else if(pid > 0){
child = waitpid(pid, &status, 0);
} else {
printf("There was an errorn");
}
}
free(cmdLine);
int walk = 0;
while(cmd[walk] != NULL) {
free(cmd[walk]);
walk++;
}
free(cmd);
}
return 0;
}

这就是所谓的遍历函数

/**
* Executes the given internal command; Nothing is returned since this is all executed on the address space
* @param cmd The command to be executed
*/
void executeInternalCommand(char** cmd) {
if(strcmp(cmd[0], "exit") == 0) {
exit(0);
} else if(strcmp(cmd[0], "cd") == 0) {
if(cmd[1] != NULL) {
chdir(cmd[1]);
}
} else if(strcmp(cmd[0], "echo") == 0) {
int temp_index = 1;
while(cmd[temp_index] != NULL) {
if(cmd[temp_index + 1] != NULL) {
snprintf(message, WRITE_BUFFER, "%s ", cmd[temp_index]);
write(STDOUT_FILENO, message, strlen(message));
} else if(cmd[temp_index] != NULL && cmd[temp_index + 1] == NULL) {
snprintf(message, WRITE_BUFFER, "%sn", cmd[temp_index]);
write(STDOUT_FILENO, message, strlen(message));
} else {
snprintf(message, WRITE_BUFFER, "n");
write(STDOUT_FILENO, message, strlen(message));
}
temp_index++;
}
} else if(strcmp(cmd[0], "help") == 0) {
if(cmd[1] == NULL) {
snprintf(message, WRITE_BUFFER, "GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)n");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "These shell commands are defined internally. 'Type help' to see this list.n");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "Type 'help name' to find out more about the function 'name'.nn");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "%-30s %-30sn", "cd [File Path]", "help name");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "%-30s %-30sn", "echo [Text]", "exit");
write(STDOUT_FILENO, message, strlen(message));
} else {
if(strcmp(cmd[1], "exit") == 0) {
snprintf(message, WRITE_BUFFER, "exitnExits the program with status code 0n");
write(STDOUT_FILENO, message, strlen(message));
} else if(strcmp(cmd[1], "cd") == 0) {
snprintf(message, WRITE_BUFFER, "cd [File Path]nChange the current directory. Accepts argument 'File Path' to change the present working directory to the 'File Path'n");
write(STDOUT_FILENO, message, strlen(message));
} else if(strcmp(cmd[1], "echo") == 0) {
snprintf(message, WRITE_BUFFER, "echo [Text]nPrints [Text] to the screenn");
write(STDOUT_FILENO, message, strlen(message));
} else {
snprintf(message, WRITE_BUFFER, "The help page for this command is currently not supportedn");
write(STDOUT_FILENO, message, strlen(message));
}
}
} else if(*cmd[0] == '!') {
printf("Banger!!!!n");
} else if(strcmp(cmd[0], "history") == 0) {
printf("History commandn");
traverseList();
}
}

编辑:我犯了一个非常新手的错误。在我的addNode函数中,我为returnNode分配了空间,并返回该空间。因此,当我从函数返回一个局部变量,并试图在方法范围之外使用它时,我显然会把内存引用搞砸。只是新手犯了一个大错误,把瞄准镜搞砸了。

这不是崩溃的根本原因,但这是一个错误。您在addnode函数中泄漏了一个对象:

void addNode(char** command) {
struct Node* tempNode = createNode(command);
if(head == NULL) {
head = malloc(sizeof(struct Node));
head = tempNode;
}

应为:

if(head == NULL) {
head = tempNode;
}

相关内容

  • 没有找到相关文章

最新更新