You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);同样无法成功,希望能正常打印结构体数组的所有元素。

问题原因
  1. 野指针问题:初始化subMenu时使用的(struct Menu[]){{...}}是临时复合字面量,它的生命周期仅局限于初始化表达式内部。初始化完成后,这个临时数组会被销毁,导致subMenu中的指针变成无效的野指针,访问时触发段错误。
  2. 格式字符串语法错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:15:35