C++ 如何使用指向自定义分配器提供的原始内存的指针(没有UB)?
我正在尝试编写一个支持分配器的容器。假设我想为三个对象分配一块内存:C++ 如何使用指向自定义分配器提供的原始内存的指针(没有UB)?,c++,c++17,language-lawyer,undefined-behavior,allocator,C++,C++17,Language Lawyer,Undefined Behavior,Allocator,我正在尝试编写一个支持分配器的容器。假设我想为三个对象分配一块内存: T* chunk = std::allocator_traits<Allocator>::allocate(allocator, 3); T*chunk=std::allocator_traits,指针运算只能在指向数组元素的指针上执行,否则会导致未定义的行为。出于同样的原因,我无法将指针转换为std::byte*,并对其使用指针算法。( STD::Apalor ToC/定义为在新分配的内存中创建一个数组,直到C
T* chunk = std::allocator_traits<Allocator>::allocate(allocator, 3);
T*chunk=std::allocator_traits,指针运算只能在指向数组元素的指针上执行,否则会导致未定义的行为。出于同样的原因,我无法将指针转换为std::byte*
,并对其使用指针算法。(<代码> STD::Apalor ToC/<代码>定义为在新分配的内存中创建一个数组,直到C++ 20,对于自定义分配器不存在同样的要求。此外,C++ 20为“隐式创建对象”添加了一些语言,但这不适用于较早的C++版本。
那么,如何计算作为construct
第二个参数的指针,而不导致未定义的行为(在C++20之前)?在最新的标准草案(C++20)中:
[选项卡:cpp17.分配器]
a、 allocate(n)-内存被分配给一个n T的数组,这样一个对象被创建,但数组元素不被构造
allocator\u traits::allocate(n)
只需调用a.allocate(n)
因此,在创建了数组之后,指针算法得到了很好的定义
在接受建议书P0593R6之前的C++17中,措辞为:
为n个类型为T的对象分配内存,但创建对象时未构造对象
在此更改之前,没有明确的方式来满足您的要求,除非:
- 我们假设自定义分配器保证创建这样的数组。这方面的问题是,在不创建对象(没有默认分配器)的情况下,没有创建数组的标准方法,因此也没有实现此类自定义分配器的标准方法
- 我们忽略了指针算法的限制。这方面的理论问题是未定义的行为。实际上,这在实际的语言实现中并不是一个问题
你是想给它贴上语言律师的标签吗?@Jeffrey我想是的,因为问题已经引用了标准。你可能会感兴趣。强制转换到std::byte*
(或[unsigned
]char*
),添加偏移量,向后强制转换,然后清洗是最安全的选择。(即使最终是正式的UB,您也无能为力。)您要求为3个未初始化的Allocator::value_type
对象的数组分配存储,其中value_type
是T
:“使用分配器a
分配n*sizeof(Alloc::value_type)
未初始化存储的字节。在存储中创建了一个类型为Alloc::value\u type[n]
的数组,但没有构造它的元素。“那么为什么指针算法不能在这里有效使用呢?这是std::vector
的一个众所周知的“不可实现性”问题。例如,请参见。
std::allocator_traits<Allocator>::construct(allocator, chunk + 2, ...);