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

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;
}

关键修改说明

  1. 二级指针的正确操作:通过临时指针temp接收*items,修改完成后再将temp赋值给*items,确保main中的指针能同步更新。
  2. 内部指针内存分配:使用strdup简化字符串内存分配(等价于malloc+strcpy),也可以手动用malloc(strlen("xxx")+1)分配足够内存后复制。
  3. 错误处理:每次内存分配后检查返回值,分配失败时清理已分配的所有内存,避免内存泄漏。
  4. 内存释放:在main中必须先释放结构体内部的字符指针,再释放结构体数组本身,否则会造成内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:55:13