realloc但只有前几个字节才有意义

前端之家收集整理的这篇文章主要介绍了realloc但只有前几个字节才有意义前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我使用过ptr = malloc(old_size);使用old_size字节分配内存块.只有第一个header_size字节才有意义.我要将大小增加到new_size.

new_size大于old_size,old_size大于header_size.

之前:

/- - - - - - - old_size - - - - - - - \
+===============+---------------------+
 \-header_size-/

后:

/- - - - - - - - - - - - - - - new_size - - - - - - - - - - - - - - - - - - -\
+===============+------------------------------------------------------------+
\- header_size-/

我不关心在ptr header_size之后存储什么,因为我会读到一些数据.

方法1:直接进入new_size

ptr = realloc(ptr,new_size);

方法2:收缩到header_size并增长到new_size

ptr = realloc(ptr,header_size);
ptr = realloc(ptr,new_size);

方法3:分配新的内存块并复制第一个header_size字节

void *newptr = malloc(new_size);
memcpy(newptr,ptr,header_size);
free(ptr);
ptr = newptr;

哪个更快?

解决方法

它几乎肯定取决于old_size,new_size和header_size的值,也取决于实现.您必须选择一些值并进行衡量.

1)最好是header_size == old_size-1&& old_size == new_size-1,因为它为您提供了单个realloc基本上是无操作的最佳机会. (2)在这种情况下应该只是稍微慢一些(2几乎没有操作比1轻微慢).

3)最好在header_size == 1&& old_size == 1024 * 1024&& new_size == 2048 * 1024,因为realloc必须移动分配,但是你要避免复制你不关心的1MB数据. (2)在这种情况下应该只是稍微慢一点.

2)当header_size远小于old_size时,可能是最好的,而new_size在realloc重新定位的合理可能范围内,但也很可能不会.那么你无法预测(1)和(3)中的哪一个会比(2)稍快一些.

在分析(2)时,我假设realloc向下大约是空闲的并返回相同的指针.这不保证.我可以想到两件可能让你烦恼的事情:

> realloc向下复制到新分配
> realloc向下拆分缓冲区以创建一个新的可用内存块,但是当你再次重新分配备份时,分配器不会再将新的空闲块直接合并到缓冲区中,以便在不复制的情况下返回.

其中任何一个都可能使(2)明显比(1)贵得多.所以这是一个实现细节,无论(2)是否是在(1)的优点(有时避免复制任何东西)和(3)的优点(有时避免复制太多)之间对冲你的赌注的好方法.

顺便说一句,这种关于性能的空闲猜测更有效,以便暂时解释你的观察,而不是暂时预测我们将在不太可能发生的事情中做出的观察,我们实际上已经足够关注性能来测试它.

此外,我怀疑对于大型分配,通过将内存重新映射到新地址,实现可能甚至可以执行重定位realloc而无需复制任何内容.在这种情况下,他们都会很快.不过,我还没有考虑实现是否真的这样做.

猜你在找的C&C++相关文章