【问题标题】:How do I insert a value in an arbitrary position in a block of memory?如何在内存块中的任意位置插入值?
【发布时间】:2010-07-03 23:03:42
【问题描述】:

我有两个 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;
}

下一个函数将OBJ 插入self->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;
}

我没有收到任何段错误或错误,只是没有按预期工作。有什么想法吗?

【问题讨论】:

    标签: c memory pointers


    【解决方案1】:

    更新:

    有两个问题,都在调用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));
    

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 2015-05-21
      • 2013-12-14
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 2011-01-16
      相关资源
      最近更新 更多