c++ - 将对象 move 到 malloc 的内存中是否有效 C++?

标签 c++ malloc move placement-new

如果内存是用malloc(而不是new)分配的,并且一个对象被 move 到该内存中,那是有效的C++吗? 假设我为 n 个类型为 T 的对象的数组分配内存,并且我有一个范围为 n 个类型为 T 的对象,我想将其移入其中,是吗?有效:

T* next = (T *)malloc(n*sizeof(T));
T* t = std::begin(my_range);
while (we still have more Ts) {
  *next = std::move(*t);   
  ++next;
  ++t;
}

这似乎可行,但我很好奇为什么会这样,因为我们从来没有在我们 move 到的已分配内存中新建对象。

我的猜测是placement new 是正确的做法:

while (we still have more Ts) {
  new (next) T(*t);
  ++next;
  ++t;
}

但我想知道为什么第一个不正确,如果是这样,它是否只是运气好或者因为 T 恰好是一个 POD。

最佳答案

If memory is allocated with malloc (as opposed to new) and an object is moved into that memory, is that valid C++?

有可能;不一定。

如果我们考虑 move-construction 那么当然,您可以使用 placement-new 来创建一个对象到内存中。有点像你的第二个例子——除了这个例子做了一个拷贝;除非迭代器很奇怪并返回一个右值。虽然,您提到的类型是 POD,但在这种情况下, move 和复制之间没有区别。

如果我们考虑 move 赋值,那么只有当之前在内存中创建了一个对象时,它才是明确定义的。在您的第一个示例中,没有创建任何对象,因此该行为在技术上是未定义的。

I'd like to know [...] if it just works by luck or because T happens to be a POD.

技术上是 UB,但如果 T 是 POD,则很可能会起作用。这种通过赋值进行的初始化在 C 中有明确的定义(也是用该语言动态创建对象的唯一方法)。

如果赋值运算符不是平凡的,那么东西很可能会崩溃。


要将一系列对象 move 到未初始化的内存中,您可能需要使用 std::uninitialized_move。无论类型的琐碎性如何,它都会被很好地定义,您甚至不必编写循环。

关于c++ - 将对象 move 到 malloc 的内存中是否有效 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54602385/

相关文章:

c++ - 链表析构函数与 Valgrind 一起执行,但不单独执行

c++ - C++ IO 流简介

c++ - 使用 {fmt} 库打印

c - 尝试分配 2D 数组后出现 EXC_BAD_ACCES

c++ - 使用 ncurses c++ (Linux) 将光标 move 到屏幕上的特定点

PHP: move 包含内容的目录?

c++ - OpenGL:计算着色器 - gl_GlobalInvocationID 提供静态输出

C Language : Why do dynamically-allocated objects return a pointer, 而静态分配的对象给你一个选择?

iphone - 释放的对象使应用程序崩溃——alloc/init 内存管理问题

c++11 - 类外定义的默认 move 操作的异常规范是什么?