如何为结构体中的结构体动态数组正确分配内存?
问题分析与解决方法
你的核心错误是混淆了指针和柔性数组的用法:你的zone结构体里的schools是school*类型的指针,而非柔性数组。你当前的分配方式虽然额外申请了3个school的内存,但zones->schools并没有指向这块内存,它是一个未初始化的野指针,直接访问必然触发段错误。
正确的内存分配步骤
需要分层逐步分配内存,对应你的三层结构体结构:
- 先分配
zone结构体本身的内存 - 给
zone中的schools指针分配3个school的内存 - 给每个
school中的competitions指针分配3个competition的内存
对应的代码实现:
#include <stdlib.h> // 你的结构体定义 typedef struct competition { int prize_1; int prize_2; int prize_3; } competition; typedef struct school { int school_id; competition *competitions; } school; typedef struct zone { school *schools; } zone; int main() { int school_count = 3; int comp_count = 3; // 1. 分配zone内存 zone *zones = malloc(sizeof(zone)); if (zones == NULL) { // 内存分配失败处理 return 1; } // 2. 分配3所学校的内存 zones->schools = malloc(sizeof(school) * school_count); if (zones->schools == NULL) { free(zones); return 1; } // 3. 给每所学校分配3项竞赛的内存 for (int i = 0; i < school_count; i++) { zones->schools[i].competitions = malloc(sizeof(competition) * comp_count); if (zones->schools[i].competitions == NULL) { // 分配失败时,释放已分配的内存避免泄漏 for (int j = 0; j < i; j++) { free(zones->schools[j].competitions); } free(zones->schools); free(zones); return 1; } // 初始化学校ID zones->schools[i].school_id = i + 1; } // 现在可以正常访问 school *cs = &(zones->schools[0]); int schoolId = cs->school_id; // 此处会得到1,无段错误 // ------------------------------ // 使用完后逐层释放内存,顺序与分配相反 // ------------------------------ for (int i = 0; i < school_count; i++) { free(zones->schools[i].competitions); } free(zones->schools); free(zones); return 0; }
额外说明
如果你原本想使用柔性数组(把schools直接嵌入zone结构体末尾),需要修改zone的定义:
typedef struct zone { // 若有其他成员,必须放在柔性数组之前 school schools[]; // 柔性数组,必须是结构体最后一个成员 } zone;
这种情况下你的初始分配方式才合理,访问时直接用zones->schools[0]即可,无需给schools指针赋值。但柔性数组在动态调整学校数量时不如指针灵活,可根据需求选择。
内容的提问来源于stack exchange,提问作者wei jong
相关产品推荐
相关产品推荐

