C语言动态嵌套结构体字段写入遇段错误,求解决方案
C语言嵌套结构体动态配置的段错误问题解决
我尝试用C语言嵌套结构体实现动态配置Section和Box数量的输入与打印功能,但在向指定Box写入字符串时触发段错误,相关代码如下:
结构体定义
struct Section { struct Box * boxes; int numBoxes; }; struct Box { char Items[1001]; };
主函数关键代码
int main(){ struct Section * allSections; int numSections; //用于内存分配的Section数量 int command, sectionNumber, boxNumber; //用于判断执行的命令 char itemType[1000]; //输入Section数量 scanf("%d", &numSections); //为所有Section分配内存 allSections = (struct Section *)malloc(numSections * sizeof(struct Section)); //循环处理命令直到终止(命令4) while (command != 4) { scanf("%d", &command); switch (command) { case 1://修改Box数量 scanf("%d", §ionNumber); if (sectionNumber > numSections) { break; } scanf("%d", &boxNumber); allSections[sectionNumber].numBoxes = boxNumber; allSections[sectionNumber].boxes = (struct Box *)malloc((allSections + sectionNumber)->numBoxes * sizeof(struct Box)); break; case 2://向Box中添加内容 scanf("%d%d", §ionNumber, &cageNumber); //注:此处变量名疑似笔误,应为boxNumber if (boxNumber >= allSections[sectionNumber].numBoxes) { break; } scanf("%s", allSections[sectionNumber].boxes[boxNumber].Items); //此处出现段错误 break;
错误分析与修正方案
核心错误点
- 未初始化
command变量:main中command未赋值就进入while (command !=4)循环,初始值为随机值,可能导致循环逻辑异常。 - Section索引越界:
allSections是长度为numSections的数组,索引范围是0~numSections-1,但代码中判断sectionNumber > numSections,若输入sectionNumber = numSections,会访问数组外的内存,触发未定义行为。 - case2变量名笔误:
scanf("%d%d", §ionNumber, &cageNumber)中的cageNumber未定义,应改为&boxNumber,否则boxNumber的值随机,后续判断和内存访问完全错误。 - 未检查
malloc返回值:如果malloc分配内存失败返回NULL,后续访问boxes指针会直接触发段错误。 - case2边界判断缺失:未先校验
sectionNumber的合法性,直接访问allSections[sectionNumber]可能越界;同时未判断boxNumber是否为负数。
修正后的关键代码示例
int main(){ struct Section * allSections; int numSections; // 初始化command,避免循环初始判断异常 int command = 0, sectionNumber, boxNumber; char itemType[1000]; scanf("%d", &numSections); allSections = (struct Section *)malloc(numSections * sizeof(struct Section)); // 检查malloc是否成功 if (!allSections) { return 1; } // 初始化每个Section的numBoxes为0,boxes为NULL for (int i = 0; i < numSections; i++) { allSections[i].numBoxes = 0; allSections[i].boxes = NULL; } while (command != 4) { // 先检查scanf的返回值,确保命令输入有效 if (scanf("%d", &command) != 1) { break; } switch (command) { case 1: if (scanf("%d", §ionNumber) != 1) break; // 修正索引判断,sectionNumber从0开始,最大为numSections-1 if (sectionNumber < 0 || sectionNumber >= numSections) { break; } if (scanf("%d", &boxNumber) != 1) break; // 避免重复分配内存导致泄漏,先释放原有内存 if (allSections[sectionNumber].boxes) { free(allSections[sectionNumber].boxes); } allSections[sectionNumber].numBoxes = boxNumber; allSections[sectionNumber].boxes = (struct Box *)malloc(boxNumber * sizeof(struct Box)); // 检查boxes的malloc是否成功 if (!allSections[sectionNumber].boxes) { allSections[sectionNumber].numBoxes = 0; } break; case 2: // 修正变量名,检查输入是否有效 if (scanf("%d%d", §ionNumber, &boxNumber) != 2) break; // 先校验sectionNumber合法性 if (sectionNumber < 0 || sectionNumber >= numSections) { break; } struct Section *sec = &allSections[sectionNumber]; // 校验boxNumber是否在合法范围,且boxes已分配 if (boxNumber < 0 || boxNumber >= sec->numBoxes || !sec->boxes) { break; } // 限制输入长度,避免Items数组溢出 scanf("%1000s", sec->boxes[boxNumber].Items); break; } } // 程序结束前释放所有内存,避免泄漏 for (int i = 0; i < numSections; i++) { free(allSections[i].boxes); } free(allSections); return 0; }
内容的提问来源于stack exchange,提问作者Dragonead
相关产品推荐
相关产品推荐

