如何解决如何使用自定义分配器无UB提供的指向原始内存的指针?
我正在尝试编写一个可识别分配器的容器。假设我想为三个对象分配一块内存:
T* chunk = std::allocator_traits<Allocator>::allocate(allocator,3);
(我知道分配器可以具有自定义的指针类型,因此我应该使用std::allocator_traits<Allocator>::pointer
;为简单起见,我在这里使用原始指针。)
现在,我想在索引2上创建一个实际的对象。我该怎么做?特别是,如何计算指向尚未存在的元素的指针?最明显的选择如下:
std::allocator_traits<Allocator>::construct(allocator,chunk + 2,...);
不幸的是,chunk + 2
似乎不正确:according to the standard,指针运算只能在指向数组元素的指针上执行,否则会导致未定义的行为。出于同样的原因,我无法将指针转换为std::byte*
并对其使用指针算术。 (虽然std::allocator
被定义为在新分配的内存中创建数组,但是直到C ++ 20时,对自定义分配器都没有相同的要求。而且,C ++ 20为“隐式创建对象”添加了一些语言。 ”,这不适用于早期的C ++版本。)
那么如何在不引起未定义行为的情况下(在C ++ 20之前)计算要作为construct
的第二个参数给出的指针?
解决方法
在最新的标准草案(C ++ 20)中:
[tab:cpp17.allocator]
a.allocate(n)-为n个T的数组分配内存,并且创建了这样的对象,但未构造数组元素。
allocator_traits::allocate(n)
只需调用a.allocate(n)
。
因此,鉴于已创建数组,指针算法已得到很好的定义。
在接受提案P0593R6之前的C ++ 17中,措辞为:
已为创建的n个类型为T的对象分配了内存,但未构造对象。
在进行此更改之前,没有明确的方法可以执行您要问的事情,除非:
- 我们假设自定义分配器可确保创建此类数组。问题在于,没有创建对象而不创建对象的标准方法(没有默认分配器),因此没有实现此类自定义分配器的标准方法。
- 我们忽略了指针运算的限制。与此相关的理论问题是不确定的行为。实际上,这对于实际的语言实现来说不是问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。