【发布时间】:2018-09-13 07:07:31
【问题描述】:
您好,我在 c 中实现了一个智能向量,但我在重新分配缓冲区时遇到了问题。
这是包含数组及其信息的结构:
struct _vector
{
item* vec;
size_t elements;
size_t size;
};
item 只是一个 typedef,在这种情况下恰好是 int。 我做了几个函数来管理数组,但是应该调整它大小的那个给我带来了问题。
(顺便说一下,Vector也是struct _vector*的typedef)
这是函数:
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);
}
}
我只是移动内容为新元素腾出空间,它工作正常,问题是重新分配数组时。 当有效元素的数量等于数组的实际大小时, 我做了一个 realloc 以使实际大小加倍。 一旦 if 激活,尽管 realloc 使程序崩溃并出现以下错误:释放对象的校验和不正确。
问题出在 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;
}
【问题讨论】:
-
如果你注释掉代码并且它神奇地工作,那通常是UB的标志
-
@yano 如果它崩溃了,那肯定是 UB :) OP 在问为什么......我猜需要 minimal reproducible example
-
您的
for循环从i=size开始,我怀疑vec[size]超出范围...但代码中可能还有未显示的 UB。 -
@yano
vec[size]将在realloc之后的范围内。 @Adonai 当你传递给insertVector时,你是如何初始化vec的? -
如果
vec->vec的第一个init是一个静态数组(不是动态分配的)那么问题就说明了。