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

向结构体数组赋值触发段错误(Segment Fault)求助

解决你的C语言结构体数组段错误问题

嘿,我一眼就揪出问题所在啦!你遇到的段错误,核心原因是没给Section_t里的header指针分配有效内存,咱们一步步拆解:

问题根源分析

你用malloc(elf_shnum * sizeof(Section_t))创建了Section_t类型的数组,这一步只给每个Section_t结构体本身分配了内存——但每个Section_t里的header是Elf_Big_Shdr_t*类型的指针,它现在是个野指针(指向随机的无效内存地址),直接去访问sections[i].header->sh_name必然触发非法内存访问,也就是段错误。

两种修复方案

方案1:把header从指针改成结构体(推荐,更简洁)

既然你需要每个Section_t都绑定一个Elf_Big_Shdr_t,不如直接把Section_t里的指针改成结构体实例,这样malloc数组时,每个header会自动获得内存空间:

修改头文件里的Section_t定义:

typedef struct {
    Elf_Big_Shdr_t header; // 将指针改为结构体实例
    unsigned char *data;
} Section_t;

然后调整主程序的赋值逻辑:

#include "readelf.h"

int main(int ac, char **av) {
    int elf_shnum, sh_name_index, i;
    Section_t *sections;

    i = 0;
    elf_shnum = 12;
    sh_name_index = 24;

    // 分配数组内存,此时每个sections[i].header都有了有效空间
    sections = malloc(elf_shnum * sizeof(Section_t));
    // 务必检查malloc是否成功!
    if (!sections) {
        perror("malloc failed");
        return 1;
    }

    // 直接访问结构体成员,无需使用指针->
    sections[i].header.sh_name = sh_name_index;

    // 程序结束前释放内存
    free(sections);
    return (0);
}

方案2:给每个header单独分配内存

如果一定要保留指针类型,那你需要遍历数组,为每个sections[i].header单独malloc内存:

#include "readelf.h"

int main(int ac, char **av) {
    int elf_shnum, sh_name_index, i;
    Section_t *sections;

    i = 0;
    elf_shnum = 12;
    sh_name_index = 24;

    sections = malloc(elf_shnum * sizeof(Section_t));
    if (!sections) {
        perror("malloc sections failed");
        return 1;
    }

    // 遍历数组,为每个header分配内存
    for (int j = 0; j < elf_shnum; j++) {
        sections[j].header = malloc(sizeof(Elf_Big_Shdr_t));
        if (!sections[j].header) {
            perror("malloc header failed");
            // 注意:如果中间分配失败,要释放已分配的内存避免泄漏
            for (int k = 0; k < j; k++) {
                free(sections[k].header);
            }
            free(sections);
            return 1;
        }
    }

    // 现在可以安全赋值了
    sections[i].header->sh_name = sh_name_index;

    // 释放内存:先释放每个header,再释放数组本身
    for (int j = 0; j < elf_shnum; j++) {
        free(sections[j].header);
    }
    free(sections);
    return (0);
}

额外提醒

  • 任何时候调用malloc都要检查返回值是否为NULL,避免内存分配失败后继续操作导致崩溃。
  • 记得在程序结束前释放所有malloc的内存,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:26:28