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
分配的大小的两倍。当您添加新元素时,此内存将被覆盖,这就是当您最终调用 realloc
时 free
失败的原因。将 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;
}
你好,我在 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
分配的大小的两倍。当您添加新元素时,此内存将被覆盖,这就是当您最终调用 realloc
时 free
失败的原因。将 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;
}