2010-07-03 80 views
2

我有两个C函数,它们基本上在堆栈数据结构上运行。这一个将类型OBJ的值推到栈顶,实际上它只是unsigned long。如果需要,堆栈也会生长。如何在一块内存中的任意位置插入一个值?

OBJ Quotation_push_(CzState *cz, CzQuotation *self, OBJ object) 
{ 
    if ((self->size + 1) > self->cap) { 
     self->items = (OBJ *)CZ_REALLOC(self->items, sizeof(OBJ) * (self->cap + 1) * 2); 
     self->cap = (self->cap + 1) * 2; 
    } 
    self->items[self->size++] = object; 
    return (OBJ)self; 
} 

下一个函数插入一个OBJself->items阵列中的任意位置。尽可能地尝试,它只是无法正常工作。我在这里使用了Quotation_push_以虚拟值来获得自动增长行为。问题是,我总是在数组末尾看到CZ_NIL虚拟值,我试图插入的项目只是覆盖已经在位置上的内容。下面是我到目前为止有:

OBJ Quotation_insert_(CzState *cz, CzQuotation *self, OBJ object, int pos) 
{ 
    printf("have to move %d OBJ from %d to %d\n", self->size - pos, pos, pos + 1); 
    Quotation_push_(cz, self, CZ_NIL); 
    memmove(self->items + ((pos + 1) * sizeof(OBJ)), self->items + (pos * sizeof(OBJ)), sizeof(OBJ) * (self->size - pos)); 
    self->items[pos] = object; 
    return (OBJ)self; 
} 

我没有得到任何内存设计缺陷或错误,它只是不正常工作。有任何想法吗?

回答

3

更新:

有两个问题,无论是在调用memmove

第一个是应该移动的字节数的错误。正确的数字是:

sizeof(OBJ) * (self->size - pos - 1) 

省略-1将会实际上搬到一个字节太多,把你的新CZ_NIL对象过去缓冲区的结束。

第二个问题是更大,但更微妙。将整数添加到指针会导致编译器执行pointer arithmetic,它会自动计算指向的对象的大小。详情请参阅this question。以下是简短版本:self->itemsOBJ的数组,因此您不需要在memmove的前两个参数中包含sizeof(OBJ)

全部放在一起,正确的函数调用是这样的:

memmove((self->items + pos + 1), 
     (self->items + pos), 
     sizeof(OBJ) * (self->size - pos - 1)); 
相关问题