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

C语言嵌套动态结构体数组realloc扩容内存异常问题咨询

嵌套动态结构体数组实现问题修复方案

存在的核心问题

  • 语法不兼容问题

    C 语言标准不支持结构体定义时给成员设置默认初始值,你代码里的= 0、= NULL这类写法是C的特性,要么你误使用C编译器编译C代码出现了隐式兼容问题,要么就是编译器扩展带来的未知行为,而且即使编译通过,动态分配的结构体成员也不会自动执行默认初始化。同时DLITEMTYPE::NOTYPE、DLITEMACTION::EDIT这种带::作用域的写法也是C++语法,C语言枚举不存在类作用域,直接使用枚举常量名即可。
  • realloc 用法错误

    直接将realloc的返回值赋值给原指针是典型错误:如果realloc申请内存失败会返回NULL,此时原指针指向的内存会直接泄漏,同时原指针变成野指针,后续访问必然触发非法内存访问。
  • 动态分配的结构体成员未初始化

    你扩容DLPage_t数组后,只给新元素的index赋值了,剩下的pageItems、pageItemCount、selectedItemIndex都是内存中的垃圾值:
    • 后续给该页添加元素时,pageItemCount是随机值,++后计算的内存大小完全错误
    • pageItems是野指针,直接传给realloc会直接触发崩溃
  • 新增的DLPageItem_t元素未初始化

    扩容pageItems数组后,新的DLPageItem_t元素所有成员都是垃圾值,后续访问逻辑必然出现异常。

修正后的实现代码

1. 修正结构体定义(符合C语法)

// 提前声明DLPageItem_t,供DLPage_t引用
typedef struct DLPageItem_t DLPageItem_t;

typedef struct
{
    uint8_t         index;
    DLPageItem_t    *pageItems;
    uint8_t         pageItemCount;
    uint8_t         selectedItemIndex;
} DLPage_t;

struct DLPageItem_t
{
    uint8_t         index;
    void            *valuePtr;
    uint16_t        tmpValue;
    DLItemType_t    type;
    uint8_t         row;
    uint8_t         col;
    uint8_t         targetPageId;
    DLItemAction_t  action;
    bool            selectable;
    bool            editing;
};

2. 修正DLPage_t数组扩容逻辑

// 用临时指针接收realloc返回值,避免申请失败内存泄漏
DLPage_t *tmp_page = realloc(this->_pages, (this->_pageCount + 1) * sizeof(DLPage_t));
if (tmp_page == NULL) {
    // 内存申请失败的错误处理逻辑,不要修改原指针和计数
    return -1;
}
this->_pages = tmp_page;
this->_pageCount++;

// 新页全量初始化,避免垃圾值
DLPage_t *new_page = &this->_pages[this->_pageCount - 1];
memset(new_page, 0, sizeof(DLPage_t));
new_page->index = this->_pageCount - 1;
// 其他自定义初始值可在此补充

3. 修正添加DLPageItem_t逻辑

// 先校验pageId合法性,避免越界
if (pageId >= this->_pageCount || this->_pages == NULL) {
    return -1;
}
DLPage_t *target_page = &this->_pages[pageId];

// 扩容item数组
DLPageItem_t *tmp_item = realloc(target_page->pageItems, (target_page->pageItemCount + 1) * sizeof(DLPageItem_t));
if (tmp_item == NULL) {
    return -1;
}
target_page->pageItems = tmp_item;
target_page->pageItemCount++;

// 新item初始化,避免垃圾值
DLPageItem_t *new_item = &target_page->pageItems[target_page->pageItemCount - 1];
memset(new_item, 0, sizeof(DLPageItem_t));
// 设置自定义初始值,注意C语言枚举直接用常量名
new_item->type = DLITEMTYPE_NOTYPE;
new_item->action = DLITEMACTION_EDIT;
// 其他自定义初始值可在此补充

额外注意事项

每次访问数组前都要校验下标合法性、指针非空,避免越界访问。如果你的项目实际使用C++开发,更推荐使用std::vector管理动态数组,自动处理内存分配、扩容和初始化逻辑,避免手动管理内存的各类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:24:02