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

C语言创建嵌套结构体时触发stack smashing detected错误排查

问题分析与解决

栈溢出(stack smashing)的核心原因是你写入的数据超出了栈上变量的分配空间,结合你的场景,90%以上是球队名称的字符数组长度不足,或者输入时未限制读取长度导致缓冲区越界。

常见错误示例

比如你可能定义了这样的结构体:

typedef struct {
    char name[5]; // 长度仅5,存不下"Japan"(5个字符+结束符'\0'需要6位)或"Germany"(7位+结束符需要8位)
    int score;
} teams;

typedef struct {
    int year, month, day;
} date;

typedef struct {
    date match_date;
    teams home;
    teams away;
} match;

当你用scanf("%s", home.name)读取"Germany"时,字符串长度(含\0)是8,但数组只有5位,多余的字节会覆盖栈上其他数据,触发系统的栈保护机制(stack protector),抛出stack smashing detected错误。

修复方案

  1. 扩大字符数组长度:给球队名称分配足够的空间,比如定义成char name[20],足够容纳绝大多数球队名字。
  2. 限制scanf的读取长度:使用带长度限制的格式符,避免输入超长字符串溢出。比如数组长度是20,就用scanf("%19s", team.name)(留1位给结束符\0)。

修正后的结构体和输入示例:

#include <stdio.h>

typedef struct {
    int year, month, day;
} date;

typedef struct {
    char name[20]; // 足够大的缓冲区
    int score;
} teams;

typedef struct {
    date match_date;
    teams home;
    teams away;
} match;

int main() {
    match game;
    
    // 输入日期示例(可根据你的逻辑调整)
    printf("输入比赛日期(年 月 日):");
    scanf("%d %d %d", &game.match_date.year, &game.match_date.month, &game.match_date.day);
    
    printf("输入主队名称、得分:");
    scanf("%19s %d", game.home.name, &game.home.score); // 限制读取19个字符
    
    printf("输入客队名称、得分:");
    scanf("%19s %d", game.away.name, &game.away.score);
    
    // 输出验证
    printf("比赛信息:%d-%d-%d\n%s %d vs %s %d\n",
           game.match_date.year, game.match_date.month, game.match_date.day,
           game.home.name, game.home.score, game.away.name, game.away.score);
    
    return 0;
}

额外注意点

  • 如果用gets()函数读取字符串,直接换掉它——gets()没有任何长度限制,必然会导致缓冲区溢出,改用fgets()或者带长度限制的scanf。
  • 编译时如果开启了-fstack-protector(多数编译器默认开启),只要栈上缓冲区越界就会触发这个错误,这是系统的保护机制,本质是内存操作违规而非逻辑错误。

内容的提问来源于stack exchange,提问作者Raul Chiarella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:10:26