【问题标题】:How to change saved address after reallocation [closed]重新分配后如何更改保存的地址[关闭]
【发布时间】:2016-03-20 01:30:40
【问题描述】:
struct AD_SINT32Type* = NULL;
foo = (struct mystructArray*)malloc(sizeof(struct mystructArray));
foo[0].x = 45;
foo[0].y = 90;
coords[0] = &foo[0];


foo = (struct mystructArray*)realloc(foo, 2 * sizeof(struct mystructArray));
foo[1].x = 30;
foo[1].y = 15;
coords[1] = &foo[1];

在此代码之后"coords[1]" 指向预期,但"coords[0]" 指向重新分配之前的旧地址。有没有办法自动适配"coords[0]"指向的地址?

【问题讨论】:

标签: c pointers memory malloc realloc


【解决方案1】:

没有完全“自动”的方法可以做到这一点,但在需要重新分配的这种情况下,您经常会看到“偏移指针”的使用。所以不要这样:

coords[0] = &foo[0];

您可以将 coords 的类型更改为 ptrdiff_t[] 并执行以下操作:

coords[0] = &foo[0] - foo;

这样,你保存的不是实际的指针,而是从分配开始的偏移量。而且这个价值永远不需要改变。

【讨论】:

  • 两个指针的差产生一个ptrdiff_t。任何其他类型都可能丢失信息。在 64 位架构 (P64) 上,uint32_t 丢失信息。
  • @Olaf:我已更新我的答案以使用ptrdiff_t。至少现在没有人可以抱怨我做了一些肮脏的事情。在 64 位上,如果您有一个巨大的数组,您只会丢失存储到 32 位 int 中的信息。只是为了让我们清楚。
  • “类似的东西”在 imo 中仍然是可疑的。 ptrdiff_t 正是为此而设计的。但是,由于差异始终是 >= 0,而您实际计算的是索引,所以 size_t 也是可以接受的。
【解决方案2】:

有没有办法自动适应“coords[0]”指向的地址?

没有。

How to update other pointers when realloc moves the memory block?

【讨论】:

    【解决方案3】:

    有没有办法自动适应“coords[0]”指向的地址?

    没有。 C 不会跟踪您存储地址的位置。如果你需要这个,跟踪是你的工作。

    另一个想法是跳出框框思考:

    • 您能否以一种不需要存储多个指向动态数组开头的指针的方式重组数据?
    • 您可以改为使用偏移量吗?

    【讨论】:

      【解决方案4】:

      只需将coords 设为size_t [](这是正确的类型)并将索引存储到foo 而不是绝对地址。

      或者,在foo 中的realloc 之后,您可以循环更新所有coords 条目。

      但第一个版本可能不会比使用地址慢多少,在变得复杂之前先进行基准测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-12
        • 2012-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多