c - C中的链表给出分段错误
问题描述
我一直致力于在 C for linux 中实现命令行提示符。基本上它使用系统调用执行命令。到目前为止所有这些都有效,但下一部分是实现历史命令,所以我通常会使用链表命令。
我得到了链表的概念,我知道它们,但我对 C 毫无希望。我似乎无法将我的小豌豆大脑包裹在它周围。所以每个节点结构都将包含命令(这是一个字符串数组),然后是指向下一个节点的指针。
我哪里错了?
节点结构定义
struct Node {
char** storedCommand;
struct Node* next;
};
全球主管定义
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 error\n");
}
}
free(cmdLine);
int walk = 0;
while(cmd[walk] != NULL) {
free(cmd[walk]);
walk++;
}
free(cmd);
}
return 0;
}
这就是所谓的 traverselist 函数
/**
* 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, "%s\n", 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'.\n\n");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "%-30s %-30s\n", "cd [File Path]", "help name");
write(STDOUT_FILENO, message, strlen(message));
snprintf(message, WRITE_BUFFER, "%-30s %-30s\n", "echo [Text]", "exit");
write(STDOUT_FILENO, message, strlen(message));
} else {
if(strcmp(cmd[1], "exit") == 0) {
snprintf(message, WRITE_BUFFER, "exit\nExits the program with status code 0\n");
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 screen\n");
write(STDOUT_FILENO, message, strlen(message));
} else {
snprintf(message, WRITE_BUFFER, "The help page for this command is currently not supported\n");
write(STDOUT_FILENO, message, strlen(message));
}
}
} else if(*cmd[0] == '!') {
printf("Banger!!!!\n");
} else if(strcmp(cmd[0], "history") == 0) {
printf("History command\n");
traverseList();
}
}
编辑:我犯了一个非常新手的错误。在我的addNode
函数中,我在那里为我的returnNode
AND 返回它分配了空间。因此,当我从函数返回一个局部变量并尝试在方法范围之外使用它时,我显然会弄乱内存引用。只是一个大的菜鸟错误弄乱了范围。
解决方案
这不是您崩溃的根本原因,但这是一个错误。您在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;
}
推荐阅读
- python - 检查numpy矩阵中特定元素的值
- python - Pandas 过滤并将日期转换为 datetime64ns
- list - wget 根据列表下载和输出
- android - 如何在android中的视图中添加旋转和调整大小按钮
- python - 如何使用 edx-dl 下载 YouTube 网址
- elasticsearch - 在 Raspberry Pi 上运行 ElasticSearch:无法创建 Java 虚拟机
- javascript - CSS类没有改变
- python-3.x - 哈希错误重命名熊猫中的列名
- html - 为什么此网格中的第三个元素与页面底部对齐?
- python - 当我尝试导入 Matplotlib 时抛出错误并且不起作用