向结构体数组赋值触发段错误(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
相关产品推荐
相关产品推荐

