【发布时间】:2010-07-02 00:06:35
【问题描述】:
是否有任何保证 realloc() 将始终就地缩小缓冲区?如下:
new_ptr = (data_type *) realloc(old_ptr, new_size * sizeof(data_type));
如果 new_size
我正在研究非 POD 数据类型数组的重新分配,如果上述行为得到保证,我认为以下策略至少可以实现有效的“收缩”:
if (new_size > old_size)
{
// malloc() a new buffer
// use placement copy constructor to copy old objects over
// free() old buffer
}
else
if (new_size < old_size)
{
// explicit destruction of unneeded objects
// realloc() buffer
}
我希望即使数据类型具有自引用/指针或其他任何内容,就地“收缩”也会很健壮......
【问题讨论】:
-
感谢大家的cmets。我想我只是觉得必须分配一个新缓冲区并进行完整复制以实现“缩小”是非常浪费和低效的......
-
这里不打算加入“不”的合唱,你现在应该明白了。但是,保证重新分配的块在收缩时重用相同内存的一个意外副作用是,您不能在 malloc/realloc 中使用 small object allocator,因为这些分配器将大小相等的对象组合在一起。
-
另一个你不能期望 realloc 总是重用相同内存的原因是大多数通用堆将管理信息(块大小,指向堆中下一个块的指针)放在“前面”的标题中分配的内存。因此,如果您有一个位于两个已分配块之间的块,并重新分配给一个较小的字,则没有空间为已释放的内存字放置标头,从而有效地丢失它并永久分割您的堆。
-
如果您尝试使用
malloc和朋友管理非 POD 数据数组,那么您将导致未定义的行为。无论这个特定问题的答案如何,您所做的都是错误的。使用new[]和delete[],或诸如std::vector之类的容器(顺便说一句,它们会原地收缩)。 -
@Mike:对不起,我不同意。使用 malloc()/free() 等结合通过放置 new() 等对 ctor/dtor 的显式调用应该得到很好的定义。大多数 std::vector 实现分别管理底层缓冲区和对象构造,而不是通过 new[]/delete[]...
标签: c++