C语言链表实现进程父子关系管理时触发SIGSEGV段错误求助
问题根因
1. 初始化逻辑BUG(核心诱因)
你写的OPTION1函数里的初始化循环存在致命错误:
for (int i = 1; i < num_processes;) { pcb_array[i].parent = -1; return; // 这里第一次循环就直接返回了! }
这段代码只会把pcb_array[1]的parent设为-1,索引≥2的PCB元素的parent都是未初始化的垃圾值,不会被设置为-1。
第一次创建子进程时,q=1是空闲的,占用后parent被设为0;第二次创建子进程时,q从1开始遍历,pcb_array[1].parent不是-1,q增加到2,此时pcb_array[2].parent是垃圾值大概率不等于-1,q会一直累加直到超出pcb_array的数组边界,访问非法内存触发SIGSEGV。
2. 其他衍生BUG
- 进程槽位越界无校验:
OPTION2里找空闲槽的while循环没有加q < num_processes的边界判断,就算所有槽位都占满也会一直往后遍历触发越界。 - 销毁逻辑错误:
OPTION3里错误调用了OPTION2,应该调用DESTROYCHILDREN销毁子进程。 - 输入合法性无校验:没有校验用户输入的父进程索引p是否在合法范围、是否已经初始化,非法输入也会触发越界。
修复方案
修复OPTION1的初始化逻辑
把循环里的return去掉,补全循环变量自增:
void OPTION1 () { printf("Enter the maximum number of processes: "); scanf("%d", &num_processes); pcb_array = malloc(num_processes *sizeof(pcb_type)); /* 初始化第一个PCB */ pcb_array[0].parent = 0; pcb_array[0].children=NULL; /* 正确初始化所有剩余PCB */ for (int i = 1; i < num_processes; i++) { pcb_array[i].parent = -1; pcb_array[i].children = NULL; // 顺带初始化children指针避免野指针 } }
修复OPTION2的空闲槽查找逻辑
增加边界判断,无空闲槽位时给出提示直接返回:
void OPTION2(){ int p; int q = 1; linked_list_type *new_child, *next; printf("Enter the parent process index: "); scanf("%d", &p); // 先校验父进程合法性 if(p <0 || p >= num_processes || pcb_array[p].parent == -1) { printf("非法的父进程索引!\n"); return; } // 查找空闲槽增加边界判断 while (q < num_processes && pcb_array[q].parent != -1) { q++; } if(q >= num_processes) { printf("没有可用的进程槽位了!\n"); return; } // 剩下的原有逻辑不变 new_child = (linked_list_type*)malloc(sizeof(linked_list_type)); new_child->process = q ; new_child->link = NULL ; pcb_array[q].parent = p; pcb_array[q].children = NULL; if (pcb_array[p].children == NULL) { pcb_array[p].children = new_child; } else { next = pcb_array[p].children; while (next->link != NULL) { next = next->link; } next->link = new_child; } PROCESSESPRINT(); }
修复OPTION3的销毁逻辑
void OPTION3() { int p; printf("Enter the index of the process whose descendants are to be destroyed: "); scanf("%d", &p); if(p <0 || p >= num_processes || pcb_array[p].parent == -1) { printf("非法的进程索引!\n"); return; } DESTROYCHILDREN(pcb_array[p].children); pcb_array[p].children = NULL; return; }
修复后即可正常创建多个子进程,不会触发段错误。
内容的提问来源于stack exchange,提问作者CompSciStudent-01
相关产品推荐
相关产品推荐

