【问题标题】:Malloc, Realloc, FreeMalloc、Realloc、免费
【发布时间】:2017-02-25 12:29:44
【问题描述】:
int *p=malloc(20);

现在堆将分配 20 字节的内存。并将第一个字节的地址返回给指针p。(假设没有返回NULL指针)。

现在我这样做,

int *q=realloc(p, 40);

现在他们有以下可能性:

1]。 q=p

2]。 q!=p

3]。 q=NULL

忘记了可能性 2 和 3。

现在我写:

free(p);

现在会发生什么?

前 20 个字节将变为空闲,其余字节仍将保持分配状态,还是所有 40 个字节都将空闲或其他?

【问题讨论】:

  • 如果realloc返回一个非空指针,则传入的指针失效(即freed),你不需要自己做。
  • 它将释放 40 个字节。只是碰巧它不需要在重新分配中移动任何东西
  • 如果q == p 传递给free 没有区别,它不知道您使用了什么变量,只知道它的值。但这是不好的做法,我认为这是一个学术问题。
  • 这不是你的问题,但标准 C 中没有办法在调用 realloc 之后测试 p==q。如果 realloc 调用移动了内存,则 p 不是有效指针,p==q 可能是未定义的行为(因为 pq 不指向同一对象的部分)。
  • @2501 是的,我已阅读您的回答并同意。

标签: c malloc free dynamic-memory-allocation realloc


【解决方案1】:

对 free 的调用将导致未定义的行为。原因如下:

函数realloc将释放指针p指向的空间指针1

p 指向的对象的生命周期2在释放时结束。

函数 free 接收到一个指向已释放空间的指针并导致未定义的行为3

另外,realloc 调用后指针 p 的值是不确定的,它的使用可能会由于陷阱表示而导致未定义的行为。

换句话说,即使从 realloc 返回的指针指向与指针 p 相同的空间的开头,由 realloc 分配的对象也算作具有新生命周期的新对象,并且可能不会使用指针 p 释放.


1(引自:ISO/IEC 9899:201x 7.22.3.5 The realloc function 2)
realloc 函数释放 ptr 指向的旧对象并返回一个 指向具有 size 指定大小的新对象的指针。

2(引自:ISO/IEC 9899:201x 7.22.3 内存管理功能1)
已分配对象的生命周期从分配开始 直到解除分配

3(引自:ISO/IEC 9899:201x 7.22.3.3 The free function 2)
否则,如果 该参数与内存管理先前返回的指针不匹配 函数,或者如果空间已通过调用 free 或 realloc 释放,则 行为未定义。

4(引自:ISO/IEC 9899:201x 6.2.4 对象的存储期限2)
当指针的值变得不确定时 它指向(或刚刚过去)的对象达到其生命周期的终点。

【讨论】:

    【解决方案2】:

    来自 malloc / realloc 手册页

    realloc() 函数试图改变分配的大小 ptr 指向的大小,并返回 ptr。如果不够 扩大空间 ptr 指向的内存分配,realloc() 创建一个新分配,尽可能多地复制 ptr 指向的旧数据 适合新的分配, 释放旧分配,并返回一个指向已分配内存的指针。

    您应该了解malloc()free()realloc() 的工作原理。 最简单的方法是使用简单的实现。

    http://arjunsreedharan.org/post/148675821737/write-a-simple-memory-allocator

    【讨论】:

    • linux 手册页通常描述函数在 linux 系统上实现的行为,这可能与标准 C 规范和其他平台上的行为不同。
    【解决方案3】:

    realloc(p,new_size) 调整 p 指向的内存块的大小,该内存块之前通过调用 malloc 或 calloc 分配。 现在,如果内存与先前分配的内存相邻,它返回与我们传递给它的指针相同的指针,就像这里 p 所以在这种情况下,如果你释放(q)p 和 q 指向的空间将被删除。

    但是如果与先前分配的内存相邻的内存不可用,那么它将为新分配的空间返回不同的指针,因此在这种情况下,如果您将释放(q)新分配的空间将被删除

    在这两种情况下,删除的内存都是 40 位

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 2018-02-04
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      相关资源
      最近更新 更多