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

C语言模拟C++ vector时内存释放报错问题求助

C语言模拟vector时free(vec->base)内存释放错误的原因与解决方法

以下是模拟vector的相关代码,在调用dispose_vector时,free(vec->base)出现内存释放错误:

结构体定义

struct vector
{
//"base"表示维护数组的起始位置,"_end"表示最后一个存储数据的下一个位置
    void** _end;
    void** base;
    size_t _capacity;
    size_t _increment;
};
typedef struct vector* vector;

初始化函数

vector create_vector()
{
    vector vec = (vector)malloc(sizeof(struct vector));
    if (!vec) {
        fprintf(stderr, "error occurred when creating the vector");
        return NULL;
    }
    vec->base = (void**)malloc(2*sizeof(void*));//初始容量为2
    if (!vec->base) {
        fprintf(stderr, "error occurred when allocating the vector base");
        free(vec); // 释放vec的内存
        return NULL;
    }
    vec->_end = vec->base;
    vec->_capacity = 2;
    vec->_increment = DEFAULT_INCREMENT;
}

销毁函数

void dispose_vector(vector vec)
{
    if (vec)
    {
        free(vec->base);//此处出现错误,不清楚原因及解决方法  
        vec -> base = NULL;
        vec->_end = NULL;
                free(vec);
         }
}

尾部添加元素函数

void push_back(vector vec, void* _val_ptr)
{
    if (vec->_end - vec->base >= vec->_capacity)
    {
        vec->base = (void* *)realloc(vec->base, vec->_capacity + vec->_increment);
        if (vec->base == NULL)fprintf(stderr, "reallocating space failed.");        
        vec->_end = vec->base + vec->_capacity;
            vec->_capacity += vec->_increment;

            for (void** it = vec->_end; it != vec->base + vec->_capacity-1; it = it + 1)
                *it = NULL;
    }
    *(vec->_end++) = _val_ptr;
}

主函数

int main()
{   
    vector vec = create_vector();
    for (int i = 1; i <= 80; ++i)//向vector中添加80个元素
    {
        char* p = (char*)malloc(sizeof(char));
        *p = 'c';
        push_back(vec,p);
    }
    for (size_t pos = 0; pos != 80; ++pos)
    {
        
        putchar(*(char*)(vec->base[pos]));
        free(vec->base[pos]);
        vec->base[pos] = NULL;
    }
    dispose_vector(vec);
    return 0;
}

错误原因

  • create_vector函数缺失返回值:函数末尾没有return vec;,导致main中获取的vec是随机垃圾地址,后续所有对vec的操作都是非法内存访问,最终触发free错误。
  • push_back中realloc内存计算错误:realloc的第二个参数是字节数,当前代码仅传入vec->_capacity + vec->_increment,但实际需要(vec->_capacity + vec->_increment) * sizeof(void*),因为每个元素是void*类型。内存分配不足会导致越界写入破坏堆结构,引发free时出错。
  • push_back中_end更新逻辑错误:扩容时先更新_end再修改_capacity,导致_end指向错误位置,后续写入越界破坏堆。

解决方法

  1. 修复create_vector的返回值:在函数末尾添加return vec;,确保返回合法的vector指针:
vector create_vector()
{
    vector vec = (vector)malloc(sizeof(struct vector));
    if (!vec) {
        fprintf(stderr, "error occurred when creating the vector");
        return NULL;
    }
    vec->base = (void**)malloc(2*sizeof(void*));//初始容量为2
    if (!vec->base) {
        fprintf(stderr, "error occurred when allocating the vector base");
        free(vec); // 释放vec的内存
        return NULL;
    }
    vec->_end = vec->base;
    vec->_capacity = 2;
    vec->_increment = DEFAULT_INCREMENT;
    return vec; // 新增返回语句
}
  1. 修正push_back的内存分配与_end更新:
void push_back(vector vec, void* _val_ptr)
{
    if (vec->_end - vec->base >= vec->_capacity)
    {
        size_t old_capacity = vec->_capacity; // 保存旧容量
        // 计算正确的内存大小:元素个数 × 每个元素的字节数
        void** new_base = (void**)realloc(vec->base, (vec->_capacity + vec->_increment) * sizeof(void*));
        if (new_base == NULL) {
            fprintf(stderr, "reallocating space failed.");
            return; // 分配失败时终止函数,避免后续错误操作
        }
        vec->base = new_base;
        vec->_capacity += vec->_increment;
        vec->_end = vec->base + old_capacity; // 基于旧容量更新_end位置

        // 新分配的内存无需手动置NULL,后续添加元素会覆盖,若有需求可保留循环但修正条件
        // for (void** it = vec->_end; it != vec->base + vec->_capacity; ++it)
        //     *it = NULL;
    }
    *(vec->_end++) = _val_ptr;
}
  1. 确保DEFAULT_INCREMENT被定义:在代码开头添加宏定义,比如#define DEFAULT_INCREMENT 10,避免使用未定义的标识符。

内容的提问来源于stack exchange,提问作者beginner for Cpp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:10:31