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指向错误位置,后续写入越界破坏堆。
解决方法
- 修复
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; // 新增返回语句 }
- 修正
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; }
- 确保
DEFAULT_INCREMENT被定义:在代码开头添加宏定义,比如#define DEFAULT_INCREMENT 10,避免使用未定义的标识符。
内容的提问来源于stack exchange,提问作者beginner for Cpp
相关产品推荐
相关产品推荐

