- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为类类型 T 的对象构造缓冲区(例如环形缓冲区)时的一个常见习惯用法是使用从 std::malloc() 或 operator new() 获得的内存地址初始化 T* 对象,然后在该缓冲区使用placement new 按需使用,使用T 指针上的指针算术遍历内存块。
虽然似乎不太可能有任何编译器无法使用它(它确实适用于 g++ 和 clang++),但在我看来,严格来说这可能具有未定义的行为。这是因为 C++17 的 §8.7/4 似乎只允许对数组进行指针运算,并且 malloc、operator new 或 operator new[] 返回的内存块不是数组——据我所知,只有 new[ ] 表达式可以在动态内存中创建一个数组,从而在构造点将其完全初始化。
这也让我想到 std::uninitialized_copy 的引用实现对于动态分配的未初始化内存具有未定义的行为,因为它在 C++17 的 §23.10.10.4/1 中的引用实现在目标迭代器上使用指针算术,这将在这里做一个指针。
如果未初始化的内存是非动态获得的,例如使用 C++17 的 §4.5/3 所允许的 unsigned char 或 std::byte 的对齐数组,则可以说这同样适用于 std::uninitialized_copy,因为在§8.7/4 暗示执行算术的目标指针类型应该是数组元素类型(unsigned char 或 std::byte),而不是使用placement new 在其中构造的类型。
这似乎令人惊讶。谁能指出这个推理中的缺陷(如果有的话)。
最佳答案
是的,从 malloc
返回的指针的指针运算或 operator new
如果没有先前的数组放置新(它本身不能可靠地完成),则具有未定义的行为,使用 std::unintialized_copy
也是如此在它上面,它被定义为表现得好像这个指针算术已经完成了。
您能做的最好的事情是创建一个 std::byte
(或 unsigned char
)数组作为存储,直接使用 new[]
,然后将新的单个对象放置到该存储数组中,这将使这些对象嵌套在缓冲区数组中。
存储数组上的指针算法是明确定义的,因此您可以使用 std::launder
访问指向存储数组中单个对象位置的指针。或者通过使用从placement-new 返回的指针,您可以获得指向嵌套对象的指针。即使这样,您也无法对指向嵌套对象的指针使用指针算术,因为它们不会形成数组。
见论文P0593R5Implicit creation of objects for low-level object manipulation有关这种令人惊讶的未定义行为的更多示例以及在 future 对其进行定义的建议。
关于c++ - std::unitialized_copy 是否有未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60465235/
为类类型 T 的对象构造缓冲区(例如环形缓冲区)时的一个常见习惯用法是使用从 std::malloc() 或 operator new() 获得的内存地址初始化 T* 对象,然后在该缓冲区使用plac
我是一名优秀的程序员,十分优秀!