为什么 C++ 分配器中没有重新分配功能?

2021-12-24 00:00:00 memory-management c++ realloc

在 C 中,标准的内存处理函数是 malloc()realloc()free().然而,C++ stdlib 分配器只并行其中两个:没有重新分配函数.当然,不可能与 realloc() 完全相同,因为简单地复制内存不适用于非聚合类型.但是,比如说,这个函数会不会有问题:

In C the standard memory handling functions are malloc(), realloc() and free(). However, C++ stdlib allocators only parallel two of them: there is no reallocation function. Of course, it would not be possible to do exactly the same as realloc(), because simply copying memory is not appropriate for non-aggregate types. But would there be a problem with, say, this function:

bool reallocate (pointer ptr, size_type num_now, size_type num_requested);

哪里

  • ptr 之前为 num_now 对象分配了相同的分配器;
  • num_requested >= num_now;
  • ptr is previously allocated with the same allocator for num_now objects;
  • num_requested >= num_now;

和语义如下:

  • 如果分配器可以将 ptr 处的给定内存块从 num_now 对象的大小扩展到 num_requested 对象,它会这样做(留下未初始化的额外内存) 并返回 true;
  • 否则它什么都不做并返回false.
  • if allocator can expand given memory block at ptr from size for num_now objects to num_requested objects, it does so (leaving additional memory uninitialized) and returns true;
  • else it does nothing and returns false.

当然,这不是很简单,但据我所知,分配器主要用于容器,而容器的代码通常已经很复杂了.

Granted, this is not very simple, but allocators, as I understand, are mostly meant for containers and containers' code is usually complicated already.

给定这样的函数,std::vector 可以如下增长(伪代码):

Given such a function, std::vector, say, could grow as follows (pseudocode):

if (allocator.reallocate (buffer, capacity, new_capacity))
  capacity = new_capacity;     // That's all we need to do
else
  ...   // Do the standard reallocation by using a different buffer,
        // copying data and freeing the current one

无法完全改变内存大小的分配器只能通过无条件的return false;来实现这样的功能.

Allocators that are incapable of changing memory size altogether could just implement such a function by unconditional return false;.

是否有如此少的具有重新分配能力的分配器实现,以至于不值得费心?还是我忽略了一些问题?

Are there so few reallocation-capable allocator implementation that it wouldn't worth it to bother? Or are there some problems I overlooked?

推荐答案

来自:http://www.sgi.com/tech/stl/alloc.html

这可能是最值得怀疑的设计决定.它会有可能对提供一个重新分配的版本要么改变了的大小现有对象无需复制或返回 NULL.这本来可以做到的对有副本的对象直接有用构造器.它也会有避免在情况下进行不必要的复制其中原始对象没有已完全填写.

This is probably the most questionable design decision. It would have probably been a bit more useful to provide a version of reallocate that either changed the size of the existing object without copying or returned NULL. This would have made it directly useful for objects with copy constructors. It would also have avoided unnecessary copying in cases in which the original object had not been completely filled in.

不幸的是,这将有禁止在 C 中使用 realloc图书馆.这反过来又会增加许多分配器的复杂性实施,并且会做出与内存调试的交互工具更难.于是我们决定反对这种选择.

Unfortunately, this would have prohibited use of realloc from the C library. This in turn would have added complexity to many allocator implementations, and would have made interaction with memory-debugging tools more difficult. Thus we decided against this alternative.

相关文章