C函数中结构体数组的内存分配问题排查
结构体指针传递与动态数组创建的问题修正
你的代码在动态内存分配和指针处理上存在几个关键问题,以下是问题分析和修正方案:
核心问题分析
- 二级指针操作错误:你需要修改
main中声明的ITEMS*指针,因此在process函数里应该操作*items(一级指针)而非items(二级指针),否则修改无法同步到main函数。 - 结构体内部指针未初始化:
name和description是字符指针,未分配内存时直接调用strcpy会导致内存访问错误,必须先为其分配有效内存。 - 内存分配尺寸错误:
realloc的大小应该是结构体数组的总字节数,即(i+1)*sizeof(ITEMS),而非基于二级指针的尺寸。 - 缺少内存分配失败检查:
realloc可能返回NULL,直接赋值会导致原有内存地址丢失,引发内存泄漏。
修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct items { int number; char *name; char *description; } ITEMS; int process(ITEMS **items) { int i = 0; const int something = 200; // 用临时指针接收*items,简化后续操作 ITEMS *temp = *items; for (int j = 100; j < something; j++) { // 重新分配结构体数组内存,检查分配是否成功 ITEMS *new_temp = realloc(temp, (i + 1) * sizeof(ITEMS)); if (new_temp == NULL) { // 分配失败时,先释放已分配的内存避免泄漏 for (int k = 0; k < i; k++) { free(temp[k].name); free(temp[k].description); } free(temp); *items = NULL; return -1; // 返回错误码 } temp = new_temp; // 为结构体内部的字符指针分配内存 temp[i].name = strdup("Some name"); // strdup自动分配内存并复制字符串 temp[i].description = strdup("Some text"); if (temp[i].name == NULL || temp[i].description == NULL) { // 内存分配失败,清理已分配资源 for (int k = 0; k <= i; k++) { if (temp[k].name) free(temp[k].name); if (temp[k].description) free(temp[k].description); } free(temp); *items = NULL; return -1; } // 赋值结构体成员 temp[i].number = j; i++; } // 将修改后的指针同步到main函数的变量 *items = temp; return i; } int main() { ITEMS *items = NULL; // 初始化为NULL,确保realloc能正确处理 int num_items = process(&items); if (num_items == -1 || items == NULL) { printf("内存分配失败\n"); return 1; } for (int i = 0; i < num_items; i++) { printf("%d - %s - %s\n", items[i].number, items[i].name, items[i].description); } // 释放内存,避免泄漏 for (int i = 0; i < num_items; i++) { free(items[i].name); free(items[i].description); } free(items); return 0; }
关键修改说明
- 二级指针的正确操作:通过临时指针
temp接收*items,修改完成后再将temp赋值给*items,确保main中的指针能同步更新。 - 内部指针内存分配:使用
strdup简化字符串内存分配(等价于malloc+strcpy),也可以手动用malloc(strlen("xxx")+1)分配足够内存后复制。 - 错误处理:每次内存分配后检查返回值,分配失败时清理已分配的所有内存,避免内存泄漏。
- 内存释放:在
main中必须先释放结构体内部的字符指针,再释放结构体数组本身,否则会造成内存泄漏。
内容的提问来源于stack exchange,提问作者Googlebot
相关产品推荐
相关产品推荐

