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

C语言中指针、结构体与函数结合使用的错误排查求助

C语言结构体柔性数组引发的段错误及修复

你的代码出现打印异常和段错误的核心原因是:Hero结构体中的char name[]是柔性数组成员,栈上直接声明Hero flash;时,这个柔性数组没有分配任何内存空间。执行strcpy(flash.name, "The Flash")会直接越界写入栈内存,破坏其他变量的内存布局,进而引发各种异常。

以下是两种可行的修复方案:

方案一:给name指定固定长度

如果英雄名称的长度是可预估的,直接给name字段设置固定大小,栈上声明的结构体就会为其分配足够空间,避免内存越界。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int power;
    int life;
    char name[64]; // 根据需求调整固定长度
} Hero;

void attackHero(Hero *hero, int *power) {
    hero->life -= *power; // 用->简化指针访问结构体成员,等价于(*hero).life

    printf("Damage: %d\n", *power);
    printf("Attacked hero: %s\n", hero->name);
    printf("Hero's remaining life: %d\n", hero->life);
}

int main () {
    Hero flash;
    flash.power = 250;
    flash.life = 500;
    strcpy(flash.name, "The Flash");
    
    Hero batman;
    batman.power = 380;
    batman.life = 700;
    strcpy(batman.name, "Batman arkham knight");

    attackHero(&flash, &batman.power);

    return 0;
}

方案二:使用动态内存分配(适用于长度不确定的场景)

柔性数组的正确用法是配合动态内存分配,先分配结构体本身的内存,再额外为name字段分配空间,总分配大小为sizeof(Hero) + 字符串长度 + 1(+1是为了存储字符串终止符\0)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int power;
    int life;
    char name[]; // 柔性数组
} Hero;

void attackHero(Hero *hero, int *power) {
    hero->life -= *power;

    printf("Damage: %d\n", *power);
    printf("Attacked hero: %s\n", hero->name);
    printf("Hero's remaining life: %d\n", hero->life);
}

int main () {
    const char* flash_name = "The Flash";
    // 分配结构体+名称的总内存
    Hero *flash = malloc(sizeof(Hero) + strlen(flash_name) + 1);
    if (!flash) { // 检查内存分配是否成功
        perror("malloc failed");
        return 1;
    }
    flash->power = 250;
    flash->life = 500;
    strcpy(flash->name, flash_name);
    
    const char* batman_name = "Batman arkham knight";
    Hero *batman = malloc(sizeof(Hero) + strlen(batman_name) + 1);
    if (!batman) {
        perror("malloc failed");
        free(flash); // 避免内存泄漏
        return 1;
    }
    batman->power = 380;
    batman->life = 700;
    strcpy(batman->name, batman_name);

    attackHero(flash, &batman->power);

    // 释放动态分配的内存
    free(flash);
    free(batman);

    return 0;
}

额外说明

  • 栈上声明的结构体不能直接使用柔性数组,因为sizeof(Hero)不会包含柔性数组的空间,必须通过动态内存分配为其补充空间。
  • hero->life是指针访问结构体成员的简化写法,和(*hero).life功能完全一致,代码更简洁。
  • 动态分配内存后必须检查返回值,避免分配失败导致空指针操作;使用完内存后要记得释放,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:51:05