根据cppref
std::allocator<T>::allocate_at_least通过调用count * sizeof(T)(可能会提供额外的std::align_val_t参数),分配未初始化存储的::operator new字节,其中count是不小于n的未指定整数值,但未指定何时以及如何调用该函数。 然后,此函数在存储中创建一个类型为T[count]的数组,并启动其生存期,但不启动其任何元素的生存期。
然而,我认为已经存在的std::allocator::allocate可以做同样的事情。
为什么我们需要 std::allocator<T>::allocate_at_least in C++23?
发布于 2021-09-08 07:17:46
allocate_at_least不做与allocate相同的事情。比较(allocate):
分配未初始化存储的
n * sizeof(T)字节.
with (allocate_at_least):
分配未初始化存储的
count * sizeof(T)字节,其中count是不小于n的未指定整数值。
此外,allocate返回:
指向类型为
n对象的数组的第一个元素的指针.
当allocate_at_least返回时:
countstd::allocation_result<T*>{p, count},其中p指向类型为T...的对象的数组的第一个元素。
因此,调用方将获得有关实际分配大小的信息。
动机可以在P0401R6;部门动机中找到
考虑向向量添加元素的代码: 向量v= {1,2,3};//预期: v.capacity() == 3 //添加一个额外的元素,触发重新分配。v.push_back(4); 许多分配器只在固定大小的内存块中分配,使请求四舍五入.我们的底层堆分配程序收到了一个12字节(
3 * sizeof(int))的请求,在为几个实现构建v时,这个请求被转换成一个16字节的区域。
发布于 2021-09-08 07:27:02
allocate可能分配比请求的更多的元素,但它无法将实际分配的大小返回给调用方。
这就是allocate_at_least的目的,它的实现可能与allocate相同,可能分配的元素数量完全相同,不同之处在于它能够返回分配给调用方的元素数,这意味着调用方可以在必要时使用这些额外的元素。
发布于 2021-09-08 07:13:29
这来自于cppref的笔记
allocate_at_least主要是为相邻的容器提供的,例如std::std::basic_string和std::basic_string,以便在可能的情况下使其容量与实际分配的大小相匹配,从而减少重新分配。 “未指定的时间和方式”的措辞使组合或优化标准库容器所做的堆分配成为可能,尽管这种优化对于直接调用::operator new是不允许的。例如,这是由libc++实现的。 在调用allocate_at_least之后,在构造元素之前,在分配的数组中很好地定义了T*的指针算术,但是如果访问元素,则行为是未定义的。
https://stackoverflow.com/questions/69098362
复制相似问题