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

C语言中结构体内部结构体指针的realloc扩容失败问题排查

排查Solid结构体Facet数组扩容失效问题

核心错误原因及修复方案

1. 未正确更新结构体的Facet数组指针

realloc可能会返回新的内存地址,若仅调用realloc但未将返回值赋值给结构体中的facets指针,原指针仍指向旧的内存块,扩容操作等于无效。

错误示例:

realloc((*sol)->facets, sizeof(facet*) * (*sol)->maxfacets * 2);
// 未接收返回值,原指针未更新

正确写法:

size_t new_max = (*sol)->maxfacets * 2;
facet **new_facets = realloc((*sol)->facets, sizeof(facet*) * new_max);
if (new_facets == NULL) {
    fprintf(stderr, "内存扩容失败\n");
    // 此处需添加内存清理逻辑避免泄漏
    free_solid(*sol);
    *sol = NULL;
    return -1;
}
// 更新结构体的数组指针和最大容量
(*sol)->facets = new_facets;
(*sol)->maxfacets = new_max;

2. 扩容后未初始化新Facet指针

realloc仅扩容内存空间,不会自动为新的数组元素分配facet结构体内存。若直接向新索引位置写入数据,会访问野指针,导致数据全0或异常。

必须在扩容后为当前待写入的Facet分配内存:

// 扩容完成后,为当前Facet分配结构体内存
(*sol)->facets[(*sol)->nfacets] = malloc(sizeof(facet));
if ((*sol)->facets[(*sol)->nfacets] == NULL) {
    fprintf(stderr, "Facet结构体内存分配失败\n");
    free_solid(*sol);
    *sol = NULL;
    return -1;
}

3. 索引与计数的顺序错误

若先递增nfacets再写入数据,会导致写入到未初始化的数组位置。正确流程应为:

  • 检查扩容
  • 为当前nfacets索引的位置分配Facet内存
  • 填充数据
  • 最后递增nfacets

完整修复后的代码片段

if (strcmp("endfacet", line) == 0) {
    // 检查是否需要扩容
    if ((*sol)->nfacets == (*sol)->maxfacets) {
        size_t new_max = (*sol)->maxfacets * 2;
        facet **new_facets = realloc((*sol)->facets, sizeof(facet*) * new_max);
        if (new_facets == NULL) {
            perror("realloc failed for facets");
            free_solid(*sol);
            *sol = NULL;
            return -1;
        }
        (*sol)->facets = new_facets;
        (*sol)->maxfacets = new_max;
    }

    // 分配当前Facet的结构体内存
    (*sol)->facets[(*sol)->nfacets] = malloc(sizeof(facet));
    if ((*sol)->facets[(*sol)->nfacets] == NULL) {
        perror("malloc failed for facet");
        free_solid(*sol);
        *sol = NULL;
        return -1;
    }

    // 填充Facet的顶点等数据(替换为实际数据收集逻辑)
    // (*sol)->facets[(*sol)->nfacets]->nvertices = collected_vtx_count;
    // memcpy((*sol)->facets[(*sol)->nfacets]->vertices, collected_vtxs, sizeof(vertex)*collected_vtx_count);

    // 递增Facet计数
    (*sol)->nfacets++;
}

验证步骤

  1. 扩容后打印(*sol)->maxfacets,确认已变为原大小的2倍
  2. 检查每个新分配的facet指针是否非空
  3. 确认数据写入的是(*sol)->facets[(*sol)->nfacets]对应的结构体,再执行计数递增

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:50:33