使用realloc与free - > malloc函数之间的差异

sta*_*tor 34 c memory-management

为什么在再次调用malloc()函数之前使用realloc()函数来调整动态分配的数组的大小而不是使用free()函数(即优缺点,优点与缺点等)?这是C编程,但我找不到合适的标签.提前致谢.

neg*_*tin 28

我知道这个问题已经很老了(它在2009年得到了回答),但我希望我的回答可以帮助那些搜索并遇到这个问题的人(比如我).

虽然这个基准测试不是确定的,因为内存管理在不同的系统中有所不同,但现在事情往往相当标准化,所以这些结果应该可以安全地用作参考点(如果你知道它不是真实的情况,请告诉我们我).我在配备4GB RAM的2.10GHz QuadCore Intel Core i3 2310M上使用Windows 7.不是有史以来最好的硬件,而是我现在拥有的最好的硬件.

此基准测试的作用是从一定量的内存(INITIAL_MEMORY)开始,并重复少量重新分配(BYTE_STEP),直到它完全分配/释放ALLOCATE_MEMORY.为此,它尝试了6种方法:

  1. 增加有损的Malloc:free()和malloc()更多内存.
  2. 减少有损的Malloc:free()和malloc()减少内存.
  3. 增加Malloc:malloc()更多内存,复制数据和free()以前的内存.
  4. 减少Malloc:malloc()减少内存,复制数据和free()以前的内存.
  5. 增加Realloc:realloc()更多内存.
  6. 减少Realloc:realloc()减少内存.

所以,首先测试:从2MB开始,以1KB步长分配±1MB:

Increasing Lossful Malloc took 3 ms
Decreasing Lossful Malloc took 5 ms
Increasing Malloc took 1 265 ms
Decreasing Malloc took 744 ms
Increasing Realloc took 316 ms
Decreasing Realloc took 0 ms
Run Code Online (Sandbox Code Playgroud)

我们可以看到,使用memcpy手动复制总是比realloc慢,因为在这种情况下,malloc保证分配新的内存,并且你被迫在每次分配中复制数据,这表明realloc确实重用了相同的地址并在某些情况下扩大块大小.因此,如果您想保留数据,realloc可能就是您想要使用的.为了简化事情,我不会继续测试这种无损的malloc方法.

让我们继续下一个测试:32MB初始内存,16MB步长16MB分配:

Increasing Lossful Malloc took 4 ms
Decreasing Lossful Malloc took 4 ms
Increasing Realloc took 21 453 ms
Decreasing Realloc took 0 ms
Run Code Online (Sandbox Code Playgroud)

现在,我们可以看到,与其他测试相比,增加realloc需要花费大量时间.减少realloc甚至没有达到1毫秒.这表明如果你不想保留你的记忆,你应该使用free-> malloc方法,或者这样做?看看这些结果:

Increasing Lossful Malloc took 777 ms
Decreasing Lossful Malloc took 729 ms
Decreasing Realloc took 19 ms
Run Code Online (Sandbox Code Playgroud)

(这些结果太接近了,所以我进行了几次测试并对它们进行了平均.)

使用realloc()时,绝对减小内存大小会更有效.这可能是因为realloc不需要搜索新的内存块,它只是使用前一个并缩小它.如果您大量使用分配,这在性能上会有很大差异.

此外,我们可以看到增加的malloc稍微慢于减少的malloc,即使两者基本相同:找到一个内存块并分配它.这种差异可能是因为当搜索更大的块时,malloc需要搜索的平均时间比搜索较小的块时要长.例如,如果有30MB的块,则分配16MB的malloc将使用它,但是分配32MB的malloc必须跳过它并继续搜索和使用时间.这可能就是为什么在我的测试中结果变化如此之大.

总结/ TLDR:

  1. 如果需要保留数据,请使用realloc().它比使用malloc()/ free()快4倍,并在扩展时复制数据.按比例缩小,速度提高10,000-100,000倍.永远不要手动复制东西.
  2. 如果你没有需要保持你的数据,你应该使用malloc()/免费()来扩大(增加内存大小),但使用realloc()的时候缩小(减少内存大小).
  3. 如果你不知道以前的大小(你不知道你是缩小还是缩小),请使用malloc()/ free().按比例缩小时,realloc()的速度提高约40倍,但放大时,realloc()的速度要慢7600倍.除非你的程序做了一些大量的分配和大量的小解除分配(分配的次数大约是分配的200倍,这是可能的),你应该使用malloc()/ free().

这是我的基准源:test.cpp

现在,请,如果我做错了或你有任何意见,请随时告诉/纠正我.


Jar*_*Par 26

优点是realloc将保留内存的内容.使用free + malloc,您需要重置数组中的数据.

  • 重新分配更快,如果有足够的空间可以更快地重新分配.否则,它转换为malloc/copy/free. (8认同)
  • 这也是缺点.如果你对数据保存不感兴趣,那么在某些情况下执行free和malloc可能会更快(因为大小增长需要移动内存块) (6认同)
  • 仍然……如果您不需要保留数据,那么free和malloc似乎更能说明您的工作。 (2认同)
  • 然后按顺序释放旧缓冲区并分配新缓冲区。malloc() 的任何体面的实现都会有效地处理它。试图通过使用 realloc() 来优化这种情况最终会失败。 (2认同)

Ste*_*dit 7

好吧,realloc可以改变块的大小,或者分配一个新的块并尽可能多地复制.相比之下,malloc和free一起只能分配一个新的,你必须自己复制.

坦率地说,realloc现在没有得到那么多的使用,因为它与C++不兼容.结果,存储器管理员倾向于不对其进行优化.