实现类std::vector的动态无符号数组时realloc报错问题排查
动态无符号数组内存重分配错误排查
在实现等效于C++ std::vector的动态无符号数组结构体时,执行push_back操作进行内存重分配时出现realloc(): invalid next size when reallocating vector错误,添加打印逻辑后偶尔还会触发malloc(): corrupted top size错误。相关代码如下:
#include <stdio.h> #include <stdlib.h> #define U_VECTOR_INITIAL_CAPACITY 1u #define U_VECTOR_GROWTH_FACTOR 2u struct UVector { unsigned* p; unsigned size; unsigned capacity; }; typedef struct UVector UVector; // "Construtor" UVector* newUVector() { UVector* vec = (UVector*) malloc(sizeof(UVector)); vec->capacity = U_VECTOR_INITIAL_CAPACITY; vec->size = 0; vec->p = (unsigned*) malloc(vec->capacity * sizeof(unsigned)); return vec; } // "Destrutor" void deleteUVector(UVector* self) { free(self->p); free(self); } void push_back(UVector* self, unsigned val) { if (self->size == self->capacity) { self->capacity *= U_VECTOR_GROWTH_FACTOR; self->p = (unsigned*) realloc(self->p, self->capacity); } self->p[self->size] = val; self->size++; } void fprintln(const UVector* self, FILE* stream) { if (self->size > 0) { fprintf(stream, "%d", self->p[0]); for (unsigned i = 1; i < self->size; ++i) fprintf(stream, " %d", self->p[i]); } fprintf(stream, "\n"); } int main() { UVector* vec = newUVector(); for (unsigned i = 0; i < 20; ++i) { push_back(vec, i); } fprintln(vec, stdout); deleteUVector(vec); return 0; }
错误原因
push_back函数中调用realloc时,传入的内存大小参数错误:
self->p = (unsigned*) realloc(self->p, self->capacity);
这里只传入了self->capacity,但实际需要分配的是元素数量 × 单个元素字节数,也就是self->capacity * sizeof(unsigned)。这个错误导致分配的内存远小于实际需要的大小,后续写入元素时会越界访问,破坏堆内存结构,从而触发内存分配相关的错误。
修复后的代码
修改push_back中的realloc调用,补充正确的内存大小计算:
void push_back(UVector* self, unsigned val) { if (self->size == self->capacity) { self->capacity *= U_VECTOR_GROWTH_FACTOR; // 修正内存大小计算:容量 × 单个元素字节数 unsigned* new_ptr = (unsigned*) realloc(self->p, self->capacity * sizeof(unsigned)); // 可选:检查realloc是否成功,避免空指针 if (new_ptr == NULL) { fprintf(stderr, "realloc failed\n"); abort(); } self->p = new_ptr; } self->p[self->size] = val; self->size++; }
另外建议给malloc和realloc添加返回值检查,避免内存分配失败后继续操作空指针,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Caio Vinícius
相关产品推荐
相关产品推荐

