C语言中无法打印结构体数组,出现段错误的技术求助
问题描述
我定义了如下C语言结构体及结构体数组:
struct Menu { float id; char item[50]; struct Menu* subMenu[10]; } Menu[5] = { {1, "SEARCH YOUR CONTACT", (struct Menu[]){{1.1, "ADD TO FAVOURITES"}, {1.2, "UPDATE"}, {1.3, "DELETE"}, {1.4, "ADD FIELD"}, {1.5, "BACK TO MAIN MENU"}}}, {2, "ADD CONTACT"}, {3, "DISPLAY FAVOURITES CONTACT", (struct Menu[]){{3.1, "ADD TO FAVOURITES"}, {3.2, "UPDATE"}, {3.3, "DELETE"}, {3.4, "ADD FIELD"}, {3.5, "BACK TO MAIN MENU"}}}, {4, "DISPLAY ALL CONTACT", (struct Menu[]){{4.1, "ADD TO FAVOURITES"}, {4.2, "UPDATE"}, {4.3, "DELETE"}, {4.4, "ADD FIELD"}, {4.5, "BACK TO MAIN MENU"}}}, {5, "EXIT APPLICATION"} }; void menuItem() { for (int i = 0; i < 5; i++) { printf(" ... %.1f \", Menu[0].subMenu[i]->id); } }
运行后输出:
... 1.1 \Error: segmention fault
尝试单独执行语句printf("%.1f", Menu[0].subMenu[1]->id);同样无法成功,希望能正常打印结构体数组的所有元素。
问题原因
- 野指针问题:初始化
subMenu时使用的(struct Menu[]){{...}}是临时复合字面量,它的生命周期仅局限于初始化表达式内部。初始化完成后,这个临时数组会被销毁,导致subMenu中的指针变成无效的野指针,访问时触发段错误。 - 格式字符串语法错误:
printf(" ... %.1f \", ...)中的引号不匹配,多余的反斜杠会导致格式字符串解析异常。
解决方法
方法1:静态子菜单数组初始化
提前定义静态存储的子菜单数组,确保其生命周期覆盖整个程序运行期,避免野指针:
struct Menu { float id; char item[50]; struct Menu* subMenu[10]; }; // 定义静态子菜单数组 static struct Menu searchSubs[] = { {1.1, "ADD TO FAVOURITES", NULL}, {1.2, "UPDATE", NULL}, {1.3, "DELETE", NULL}, {1.4, "ADD FIELD", NULL}, {1.5, "BACK TO MAIN MENU", NULL} }; static struct Menu favSubs[] = { {3.1, "ADD TO FAVOURITES", NULL}, {3.2, "UPDATE", NULL}, {3.3, "DELETE", NULL}, {3.4, "ADD FIELD", NULL}, {3.5, "BACK TO MAIN MENU", NULL} }; static struct Menu allSubs[] = { {4.1, "ADD TO FAVOURITES", NULL}, {4.2, "UPDATE", NULL}, {4.3, "DELETE", NULL}, {4.4, "ADD FIELD", NULL}, {4.5, "BACK TO MAIN MENU", NULL} }; // 初始化主菜单 struct Menu Menu[5] = { {1, "SEARCH YOUR CONTACT", {searchSubs, searchSubs+1, searchSubs+2, searchSubs+3, searchSubs+4}}, {2, "ADD CONTACT", {NULL}}, {3, "DISPLAY FAVOURITES CONTACT", {favSubs, favSubs+1, favSubs+2, favSubs+3, favSubs+4}}, {4, "DISPLAY ALL CONTACT", {allSubs, allSubs+1, allSubs+2, allSubs+3, allSubs+4}}, {5, "EXIT APPLICATION", {NULL}} }; void menuItem() { for (int i = 0; i < 5; i++) { // 增加空指针判断,避免越界访问 if (Menu[0].subMenu[i] != NULL) { printf(" ... %.1f\n", Menu[0].subMenu[i]->id); } } }
方法2:带static的复合字面量(C99+)
如果编译器支持C99标准,在复合字面量前加static关键字,将临时数组转为静态存储,延长其生命周期:
struct Menu { float id; char item[50]; struct Menu* subMenu[10]; } Menu[5] = { {1, "SEARCH YOUR CONTACT", (static struct Menu[]){{1.1, "ADD TO FAVOURITES"}, {1.2, "UPDATE"}, {1.3, "DELETE"}, {1.4, "ADD FIELD"}, {1.5, "BACK TO MAIN MENU"}}}, {2, "ADD CONTACT"}, {3, "DISPLAY FAVOURITES CONTACT", (static struct Menu[]){{3.1, "ADD TO FAVOURITES"}, {3.2, "UPDATE"}, {3.3, "DELETE"}, {3.4, "ADD FIELD"}, {3.5, "BACK TO MAIN MENU"}}}, {4, "DISPLAY ALL CONTACT", (static struct Menu[]){{4.1, "ADD TO FAVOURITES"}, {4.2, "UPDATE"}, {4.3, "DELETE"}, {4.4, "ADD FIELD"}, {4.5, "BACK TO MAIN MENU"}}}, {5, "EXIT APPLICATION"} }; void menuItem() { for (int i = 0; i < 5; i++) { // 修正格式字符串的引号错误 printf(" ... %.1f\n", Menu[0].subMenu[i]->id); } }
额外注意事项
- 必须修正
printf的格式字符串,移除多余的反斜杠,保证引号匹配。 - 建议给
subMenu数组的末尾元素赋值NULL,遍历通过空指针判断终止循环,防止越界访问。
内容的提问来源于stack exchange,提问作者nomnom
相关产品推荐
相关产品推荐

