realloc 的问题,使程序崩溃

Problems with realloc, makes program crash

你好,我在 c 中实现了一个智能向量,我在缓冲区的重新分配方面遇到了问题。

这是包含数组及其信息的结构:

struct _vector
{
    item* vec;
    size_t elements;
    size_t size;
};

item 只是一个 typedef,在这种情况下恰好是 int。 我做了几个函数来管理数组,但是应该调整它大小的函数给我带来了问题。

(Vector 也是 struct _vector* 的类型定义)

这是函数:

void insertVector(const Vector vec,const int pos,const item a)
{
    if(vec->elements==vec->size)
    {
        item* temp=realloc(vec->vec,(vec->size*2)*sizeof(item));
        if(temp==NULL)
        {
            puts("Error: space unavailable");
            return;
        }
        //vec->vec=realloc(vec->vec,(vec->size*2)*sizeof(item));
        vec->vec=temp;
        vec->size*=2;
    }
    int size=vec->elements;
    if(pos>=0&&pos<=size)
    {
        for(int i=size;i>pos;i--)
        {
            vec->vec[i]=vec->vec[i-1];
        }
        vec->vec[pos]=a;
        vec->elements+=1;
        printf("size is %lu\nelements are %lu\n",vec->size,vec->elements);
    }
}

我只是将内容移动到 space 用于新元素,它工作正常,问题是数组重新分配时。 当有效元素的数量等于数组的实际大小时, 我做了一个 realloc 来加倍实际大小。 一旦 if 激活,尽管 realloc 使程序崩溃,并使用此 error:incorrect 已释放对象的校验和。

问题出在 if 中,因为它只会在大小和元素相等时崩溃,如果我注释掉该部分,一切正常 我不知道会是什么。

编辑: 我用来创建和初始化我正在使用的实例的函数是:

Vector newVector(void)
{
    Vector new=malloc(sizeof(*new));
    new->vec=NULL;
    new->elements=0;
    new->size=0;
    return new;
}

void initVector(const Vector vec,const size_t size) 
{
    vec->vec=calloc(size,sizeof(item));
    vec->elements=size;
    vec->size=size*2;
}

在您的 initVector 函数中,您设置的大小不正确,是您使用 calloc 分配的大小的两倍。当您添加新元素时,此内存将被覆盖,这就是当您最终调用 reallocfree 失败的原因。将 initVector 更改为:

void initVector(const Vector vec,const size_t size) 
{
    vec->vec=calloc(size,sizeof(item));
    vec->elements=size;
    vec->size=size;
}

根据您的评论

I created a new vector setting to zero every field, then i used this function:

void initVector(const Vector vec,const size_t size) 
{ 
    vec->vec=calloc(size,sizeof(item));
    vec->elements=size;
    vec->size=size*2; 
}

我认为您错误地处理了元素的大小和数量。这 initVector 函数只是为 vec->vec 数组分配内存,所以 vec->elements 应该是 0,而不是 size。而vec->size应该是size,不是 size*2。所以正确的函数应该是

// remove the const, you are modifying the data vec is pointing to
int initVector(Vector vec, size_t size)
{
    if(vec == NULL)
        return 0;

    vec->vec = calloc(size, sizeof *vec->vec);
    if(vec->vec == NULL)
        return 0;

    vec->elements = 0;
    vec->size = size;
    return 1;
}

现在 insertVector 只会分配新的 space,当所有分配 space 时 被使用了。

并且我建议你使用memmove复制内存:

// again, remove the const here
int insertVector(Vector vec, const size_t pos, const item a)
{
    if(vec == NULL)
        return 0;

    if(vec->elements==vec->size)
    {
        item* temp=realloc(vec->vec,(vec->size*2)*sizeof *temp);
        if(temp==NULL)
        {
            fprintf(stderr, "Error: space unavailable\n");
            return 0;
        }

        vec->vec=temp;
        vec->size*=2;
    }

    // I use vec->elements as upper limit,
    // otherwise you could have "holes" in the array and
    // you wouldn't realize it.
    if(pos < 0 || pos > vec->elements)
    {
        fprintf(stderr, "invalid position\n");
        return 0;
    }

    memmove(vec->vec + pos + 1, vec->vec + pos, (vec->elements - pos) * sizeof *vec->vec);

    vec->vec[pos] = a;
    vec->elements += 1;

    printf("size is %lu\nelements are %lu\n",vec->size,vec->elements);

    return 1;
}