【问题标题】:Does realloc change pointer address?realloc 会改变指针地址吗?
【发布时间】:2016-05-26 15:07:32
【问题描述】:

以这段代码为例:

Struct* allocSomething(void) {
    int n; 
    Struct *something = malloc(n*sizeof(Struct));
    return something;
}

Struct* reallocSomething(Struct **s) {
    int n;
    Struct *something = realloc(*s, (n*sizeof(int)) - 1 * sizeof(Struct));
    return something;
}

int main() {
    Struct *point = allocSomething();
    //code does something...
    point = reallocSomething();
    free(point);
}

我的问题是,在调用reallocSomething 之后,point 仍然与allocSomething 返回的地址相同?比如point有地址0x01,当这个指针被reallocSomething重新分配时,那个地址还是0x01吗?

【问题讨论】:

  • 编译器警告是你的朋友。启用并注意他们!并阅读文档。

标签: c function malloc realloc


【解决方案1】:

来自realloc 的手册页:

void *realloc(void *ptr, size_t size);

....

realloc() 返回一个指向新分配内存的指针,它 适合任何类型的变量对齐并且可能不同 来自 ptr,如果请求失败,则为 NULL。如果大小等于 0, 返回 NULL 或适合传递给 free() 的指针。 如果 realloc() 失败,原始块保持不变;它不是 释放或移动。

由于realloc 可能会将分配的内存移动到新位置,因此您需要考虑这一点。

【讨论】:

    【解决方案2】:

    不要指望它留在同一个地址。无论出于何种原因,系统都可以将整个事件转移到不同的地址。虽然您请求的内存块较小,并且它在逻辑上应该适合先前分配腾出的空间,但这不是原子操作,任何中断或分时都可以让其他东西抢占该内存空间。无论您使用什么系统,都可能有其他恶作剧,但标准方面?不要指望地址保持不变。也不要指望它会改变。

    【讨论】:

    • (缺乏)原子性与什么有什么关系?
    • 这意味着调度程序可以中断程序并让其他东西在 realloc 调用的中间运行。你知道,如果他的系统有其中之一。如果有其他东西在运行,它可以 malloc 并获取地址。我试图解释为什么系统会给他一个新地址而不是保留旧地址。
    • 这仍然没有任何意义。其他程序看不到相同的内存(除非它们使用共享内存,这不是由[m/c/re]alloc() 而是由实现定义的原语(例如mmap())处理的)。其他线程 可能会看到realloc()call 的非原子性,但前提是分配已交给其他线程,然后在realloc()-call 完成之前交回。由于这将需要一个不必要的完整副本额外的内存,这只会是一个疯狂的实现的问题。面对现实,原子性是一个红鲱鱼。
    【解决方案3】:

    从标准的角度来看,除非 realloc 失败,否则调用它的行为不仅会破坏旧指针标识的存储,还会破坏旧指针本身。如果代码试图访问旧指针而不是通过检查其字节,编译器可能会以任意和反复无常的方式运行,即使该指针中的位模式恰好与新指针的位模式精确匹配。

    质量实现可能(并且可能应该)允许程序以超出标准要求的某些方式使用 realloc(例如,检查对象是否已移动,如果已移动,则重新计算标识其部分的指针,但不要打扰如果它没有移动,那么这样的计算),但标准没有定义指示可以通过哪些方式来指示它们是否支持这样的构造。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多