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

实现类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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:37:37