在realloc中使用struct值会产生分段错误

时间:2016-10-23 09:25:42

标签: c vector struct

使用C我有一个如下所示的结构:

typedef struct {
void * elems;
int logLen;
int allocLen;
int elemSize;
void (*vecFree)(void *);
int initAlloc;
} vector;`

我也有功能:

void VectorNew(vector *v, int elemSize, VectorFreeFunction freeFn, int initialAllocation)
{   printf("%s\n" , "vecNew");
assert(elemSize > 0);
assert(initialAllocation >-1);
if(initialAllocation == 0) {
    v->initAlloc = 15;
    v->allocLen = v->initAlloc;
}
else {
    v->initAlloc = initialAllocation;
    v->allocLen = v->initAlloc;
}
v->elemSize = elemSize;
v->elems = malloc(v->elemSize*v->allocLen);
v->logLen = 0;
v->vecFree = freeFn;
}

void VectorAppend(vector *v, const void *elemAddr)
{   printf("%s\n" , "vecAppend");
if(v->logLen == v->allocLen)
    growVector(v);
void * dest = point(v,v->logLen,v->elemSize);
dest = memcpy(dest,elemAddr,v->elemSize);
v->logLen++;
}

并且growVector函数如下所示:

void growVector(vector *v){
printf("%s\n" , "vecGrow");
v->allocLen +=v->initAlloc;
v->elems = realloc(v->elems,(v->elemSize) * (v->allocLen));
}

问题出在vectorNew期间我正确传递了elemSize = 1initialAllocation = 4和其他参数。 然后我使用vectorAppend 4次。之后我再次使用vecotrAppend,但allocLen等于logLen,因此必须转到vectorGrow以及发生分段错误的地方。

1 个答案:

答案 0 :(得分:0)

您使用宏point错误。

void VectorAppend(vector *v, const void *elemAddr)
{   
    printf("%s\n" , "vecAppend");
    if(v->logLen == v->allocLen)
        growVector(v);

    void * dest = point(v->elems,v->logLen,v->elemSize); // starting point is at v->elems
    dest = memcpy(dest,elemAddr,v->elemSize);
    v->logLen++;
}

说明:结构中的第一个条目(elems)指向为向量条目分配的内存(但它不是用于元素本身的内存)。你第一次调用VectorAppend时覆盖了这个字段(由于内存属于进程,程序此时不会崩溃)。然后,当您尝试调用realloc操作系统查看字段elems时,将elems字段指向的内存复制到新位置并释放旧内存。由于覆盖的字段没有指向内存,因此您的进程已将其分配为崩溃。