11

realloc用于动态重新分配内存。

假设我使用该malloc函数分配了 7 个字节,现在我想将其扩展为 30 个字节。

如果内存中没有 30 字节的连续(单行连续)空间,后台会发生什么?

是否有任何错误或将部分分配内存?

4

5 回答 5

11

realloc幕后工作大致是这样的:

  • 如果当前块后面有足够的空闲空间来满足请求,则扩展当前块并返回一个指向块开头的指针。
  • 否则,如果其他地方有足够大的空闲块,则分配该块,从旧块复制数据,释放旧块并返回指向新块开头的指针
  • 否则通过返回报告失败NULL

因此,您可以通过测试来测试失败NULL,但请注意不要过早覆盖旧指针:

int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
  int* temp = realloc(p, y);
  if (NULL == temp)
  {
    /* Handle error; p is still valid */
  }
  else
  {
    /* p now possibly points to deallocated memory. Overwrite it with the pointer
       to the new block, to start using that */
    p = temp;
  }
}
于 2010-09-10T11:55:50.540 回答
6

realloc只有当它可以返回一个连续的(用你的话来说是“顺序的”)内存块时,它才会成功。如果不存在这样的块,它将返回NULL.

于 2010-09-10T11:38:07.577 回答
1

手册页

realloc() 返回一个指向新分配内存的指针,该指针适合任何类型的变量对齐,并且可能与 ptr 不同,如果请求失败,则返回 NULL。

所以换句话说,要检测失败,只需检查结果是否为NULL。

编辑:如评论中所述,如果调用失败,则不会释放原始内存。

于 2010-09-10T11:38:00.090 回答
1

一般来说,这取决于实现。在 x86(-64) Linux 上,我相信标准 doug lea malloc 算法将始终分配至少一个标准 x86 页面(4096 字节),因此对于您上面描述的场景,它只会重置边界以容纳额外的字节。比如说,将 7 字节的缓冲区重新分配给 PAGE_SIZE+1,我相信它会尝试分配下一个连续页面(如果可用)。

如果您在 Linux 上开发,值得阅读以下内容:

默认情况下,Linux 遵循乐观的内存分配策略。这意味着当 malloc() 返回非 NULL 时,不能保证内存确实可用。这是一个非常糟糕的错误。如果发现系统内存不足,一个或多个进程将被臭名昭著的 OOM 杀手杀死。如果在不希望突然丢失一些随机选择的进程的情况下使用 Linux,并且内核版本足够新,则可以使用以下命令关闭这种过度使用行为:

# echo 2 > /proc/sys/vm/overcommit_memory

另请参阅内核文档目录、文件 vm/overcommit-accounting 和 sysctl/vm.txt。

于 2010-09-10T11:54:30.870 回答
0

FreeBSD 和 Mac OS X 具有 reallocf() 函数,当请求的内存无法分配时,该函数将释放传递的指针(参见 man realloc)。

于 2010-09-10T12:04:18.917 回答