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

二次调用内存释放函数触发段错误问题排查

C语言结构体释放时的段错误问题

问题场景与代码

定义的结构体如下:

typedef struct TrapAttribute {
    char name[16];
    uint8_t type;
} TrapAttribute;

typedef struct TrapBlockType {
    uint16_t id;
    char name[16];
    
    SDL_Texture **textures;
    uint8_t texturesCount;
    TrapAttribute **attributes;
    uint8_t attributesCount;
} TrapBlockType;

对应的内存释放函数:

void TrapFreeAttributesList(TrapBlockType *type, uint8_t count){
    for (int i = 0; i < count; i++){
        free(type->attributes[i]);
    }
    free(type->attributes);
}

void TrapFreeTexturesList(TrapBlockType *type, uint8_t count); //本问题无需完整代码

void TrapFreeBlockType(TrapBlockType *type){
    TrapFreeAttributesList(type, type->attributesCount);
    TrapFreeTexturesList(type, type->texturesCount);
    free(type);
}

执行释放操作时,第一个结构体释放正常,第二个触发段错误:

TrapBlockType **list; //此处省略完整代码,该列表包含两个TrapBlockType *
TrapFreeBlockType(list[0]);
printf("Block type number 0 successfully freed\n");
TrapFreeBlockType(list[1]); //此处触发段错误
printf("Block type number 1 successfully freed\n");

经测试,段错误出现在TrapFreeAttributesList的循环条件判断处:

void TrapFreeAttributesList(TrapBlockType *type, uint8_t count){
    for (int i = 0; i < count; i++){ //第二次调用时在此处触发段错误
        free(type->attributes[i]);
    }
    free(type->attributes);
}

将TrapFreeAttributesList的代码直接移入TrapFreeBlockType执行,问题依旧。

根本原因分析

1. 野指针/重复释放

如果两个TrapBlockType实例共享了同一个attributes数组,或者其中的某个TrapAttribute指针,第一次释放会将这些内存归还给系统。第二次释放时,访问的是已经失效的野指针,直接触发段错误。

2. 结构体初始化错误

第二个TrapBlockType的attributes指针未正确初始化(比如为NULL但attributesCount不为0),或者attributes数组内的元素是未分配内存的野指针。第一次释放未触发错误只是巧合,第二次操作刚好命中非法内存区域。

3. 内存越界污染

在创建或使用list的过程中,存在内存写越界操作,覆盖了第二个TrapBlockType的attributes指针或attributesCount的值。比如第一次释放时的内存操作越界,破坏了第二个结构体的关键字段,导致第二次释放时循环条件(i < count)中的count变成非法值,或type->attributes指向了无效内存。

针对循环条件触发错误的具体说明

段错误出现在i < count判断时,大概率是count(即type->attributesCount)被非法修改为一个极大值,导致i递增后访问了超出栈或数组范围的内存;或者type本身就是野指针(比如list[1]已被意外释放或覆盖)。

排查建议

  • 检查list的填充逻辑,确保两个TrapBlockType的attributes、attributesCount都是独立分配、正确初始化的,不存在指针共享。
  • 创建TrapBlockType时,确保未分配attributes数组时,attributesCount设为0;每个attributes[i]都通过malloc等函数分配了合法内存。
  • 使用内存检测工具(如Valgrind),直接定位非法内存访问的具体位置和原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:37:03