正在将对象移动到malloc';d内存有效C++;? 如果内存分配了 MalOC (与新< /C> >相反),对象被移动到那个内存中,那是有效的C++吗? 假设我为类型为T的n个对象的数组分配内存,并且我有一个类型为T的n个对象的范围,我想进入其中,这是否有效: 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; }

正在将对象移动到malloc';d内存有效C++;? 如果内存分配了 MalOC (与新< /C> >相反),对象被移动到那个内存中,那是有效的C++吗? 假设我为类型为T的n个对象的数组分配内存,并且我有一个类型为T的n个对象的范围,我想进入其中,这是否有效: 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; },c++,malloc,move,placement-new,C++,Malloc,Move,Placement New,这似乎是可行的,但我很好奇为什么会这样,因为我们从未在分配的内存中创建新的对象 我想新的安置方式是正确的: while (we still have more Ts) { new (next) T(*t); ++next; ++t; } 但是我想知道为什么第一个是不正确的,如果是这样的话,是因为运气好还是因为T恰好是一个豆荚 如果内存分配了MALLC(与new相反),对象被移动到那个内存中,那就是有效的C++?< /p> 潜在的;不一定 如果我们考虑移动构造然后确定,你可以使用放置

这似乎是可行的,但我很好奇为什么会这样,因为我们从未在分配的内存中创建新的对象

我想新的安置方式是正确的:

while (we still have more Ts) {
  new (next) T(*t);
  ++next;
  ++t;
}
但是我想知道为什么第一个是不正确的,如果是这样的话,是因为运气好还是因为
T
恰好是一个豆荚

如果内存分配了MALLC(与new相反),对象被移动到那个内存中,那就是有效的C++?< /p> 潜在的;不一定

如果我们考虑移动构造然后确定,你可以使用放置new来创建一个对象到内存中。有点像你的第二个例子——除了这个例子是复制的;除非迭代器很奇怪并返回右值。尽管如此,您提到的类型是POD,在这种情况下,移动和复制之间没有区别

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

我想知道[…]它是靠运气还是因为T碰巧是一个豆荚

技术上是UB,但如果
T
为POD,则很可能工作。这种类型的赋值初始化在C语言中有很好的定义(也是用该语言动态创建对象的唯一方法)

如果赋值操作符是非平凡的,那么东西很可能会破裂



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

为什么不呢?C++提供了代码> CSTDLIB < /C>,以提供C类型<代码> MalC/CalLog/RealLC/函数。您使用的是
new/delete
还是
malloc/free
,很大程度上取决于您承担了什么样的验证责任。并没有规定具体的分配方案。我认为这可能取决于这一行动是如何发生的。如果对象X释放一个资源作为移动分配左侧的一部分,并且该资源未初始化,因为它是
malloc
ed并且没有构造,那么所有的错误都可能发生。尝试T的任何复杂类型,例如
std::string
,您将看到为什么使用malloc是一种不好的做法。放置新的是一个正确的方法,但你必须负责调用析构函数。这就是我的想法。但是,如果第一个示例调用移动构造函数而不是移动赋值操作符,那么它是正确的,对吗?因此它归结为使用移动构造函数而不是移动赋值操作符。可以使用新位置调用移动构造函数吗?像这样:新的(下一个)T(std::move(*T))@菲利普:是的。所有相同的构造函数都可以通过placement new、Allocation new或variable definition来使用。