【问题标题】:Preformance of reallocrealloc的性能
【发布时间】:2014-07-18 18:19:57
【问题描述】:

看起来realloc 不会释放旧内存(无论成功还是失败),而vector 总是删除旧内存并分配一个新块。

我可以说对于 POD 数据,realloc 的性能比 vector 更好吗?

例如:

int *p = malloc(5 * sizeof(int));
...
int *new_p = (int*) realloc(p, 10 * sizeof(int));

旧内存p会在这里释放吗?

【问题讨论】:

  • 这个link 可能会有所帮助。
  • 你误会了 realloc() 没有释放旧内存。
  • 好的,看来我不明白realloc 的工作原理,有人解释一下吗?谢谢。
  • 了解什么?有什么问题?
  • @Deqing: realloc 将尝试调整现有区域的大小。如果这不起作用,它将尝试分配一个新区域,复制旧数据然后释放旧区域。如果这也不起作用,则返回NULL(失败),但这样做不会破坏原始数据(允许调用者进行合理的恢复并可能解决问题)。跨度>

标签: c++ c memory vector realloc


【解决方案1】:

Realloc 可以扩展实际分配(如果可能的话)或者可以分配一个新块,复制旧块值并释放旧块。在第一种情况下它有更好的性能,但是,由于你事先不知道它会做什么,你必须假设指向旧块的指针将变得无效。

【讨论】:

  • 您最初的陈述是错误的;如果是真的,这个:if (new_p) free(p); 总是会导致 UB。 编辑等一下。我会误会吗?这是一个相当常规的声明;但请参阅,例如,en.cppreference.com/w/c/memory/realloc
  • 我不明白你的意思。即使 realloc 增加了分配,它也会返回一个指向分配区域的指针(在这种情况下是 new_p == p)。
  • 我的错,我记错了。如果需要,realloc 已经释放了原始内存。我一定是把这个和更常见的问题“如果realloc 失败了怎么办?”混淆了。
  • 第一种情况正是我要问的,尽管我同意旧块很可能变得无效。
【解决方案2】:

唯一显着的区别(忽略“语法糖”)是realloc() 可能会尝试增加现有区域的大小;而vector不能这样做,因此总是必须分配一个新区域,将旧数据复制到新区域,然后释放旧区域。

基于此,有两种情况realloc() 会更胜一筹。第一个是当数据很大时(因此复制所有数据的成本很高)并且能够增加区域的大小可以避免昂贵的复制。

第二种情况是您根本没有足够的(虚拟)内存来允许同时存在 2 个副本。例如,如果您在一台 32 位计算机上,有 2 GiB 的空间可用于数据,并且您有一个 1.5 GiB 的阵列,那么您不能分配第二个 1.5 GiB 阵列(空间不足)并且必须扩大现有区域或失败。

请注意,对于这两种情况(相对罕见),realloc() 和向量都可能不如其他方法。举一个简单的例子,而不是拥有一个巨大的数组,也许您可​​以将它分解为“子数组”的链表(例如,1000 个“子数组”的链表,每个 1.5 MiB 而不是单个 1.5 GiB 数组; 这样就很容易创建一个新的“子数组”并将其添加到列表的末尾)。当然,其他方法也有缺点(例如,对于“子数组的链表”示例,迭代变得稍微复杂一些)。

【讨论】:

  • 谢谢,非常实用的回答。
猜你喜欢
  • 2017-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 2011-05-10
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多