【问题标题】:C++ std::copy vs std::uninitialized_copy [duplicate]C++ std::copy vs std::uninitialized_copy [重复]
【发布时间】:2020-03-29 04:36:53
【问题描述】:

c++ 新手在这里。我很难理解这两种方法之间的区别。 在这种情况下,“就地”是什么意思。文档http://www.cplusplus.com/reference/memory/uninitialized_copy/

与算法复制不同,uninitialized_copy 构造对象 就地,而不是仅仅复制它们。

我在看书Accelerated C++ by Andrew Koenig and Barbara E. Moo,解释差异的时候也显得有些含糊

uninitialized_copy 函数的操作类似于库副本 function [...] 它假定目标范围包含原始存储,而不是 已经持有值的元素。

但是如果你在一块已经包含元素的内存上调用unitialized_copy会发生什么?我已经尝试过了,它似乎工作得很好,但我确信有两个不同的功能是有充分理由的,我想知道这是什么原因。

【问题讨论】:

  • the Possible Implementation given here 看来,它在给定存储上使用placement new 而不清理任何已经存在的东西。如果该存储中有任何有效对象,它们会被覆盖而不会被销毁。没有析构函数,没有 RAII,没有清理。很可能泄漏-城市。
  • 对于它的价值,cplusplus.com 在这里以不是一个好的来源而闻名。 cppreference.com 通常被认为更好。
  • @user4581301 我认为这一定是真的,但我觉得奇怪的是,文档中没有明确提到这是关键的区别。
  • @BorisLipschitz 之类的,这个答案是否暗示copy 将调用现有内存对象上的赋值构造函数......而 uninitialized_copy 将调用复制构造函数?

标签: c++


【解决方案1】:

在这种情况下,“就地”是什么意思。

使用placement-new 表达式“就地”构造一个对象意味着存在一个现有的存储跨度,该对象被构造到其中。这与 allocating-new 不同,后者会分配一块新的动态存储,在其中创建对象。

但是如果你在一块已经包含元素的内存上调用 unitialized_copy 会发生什么?

取决于现有对象的类型。如果该类型是可简单破坏的,那么被覆盖对象的生命周期就结束了。

如果类型不是可轻易破坏的,那么使用 std::unitialized_copy 将对象构造到它们的位置会导致未定义的行为。


请注意,相比之下,std::copy 不会创建任何对象。它在其生命周期不受操作影响的现有对象上调用赋值运算符。 (虽然,重载的赋值运算符可能会间接导致对象的创建)。

std::uninitialized_copy 有用的一种情况是重用原始内存,例如在std::vector 的实现中。

【讨论】:

  • 那么,说copy 将调用现有内存对象上的赋值构造函数/运算符是否正确......并且uninitialized_copy 将调用您正在插入的对象的copy constructor 和将结果放在内存中(覆盖那里的任何内容)
  • @FRR 没有赋值构造函数之类的东西。但除此之外,是的。
【解决方案2】:

std::uninitialized_copy 用于非常特殊的情况,您必须将对象传递到您显式控制的内存中,例如使用特殊的内存分配器、保留的内存区域等。

因此,如果您没有很好的理由使用std::uninitialized_copy,请不要使用它。

【讨论】:

    猜你喜欢
    • 2015-07-21
    • 2018-08-19
    • 1970-01-01
    • 2020-09-14
    • 2013-01-25
    • 2015-01-05
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多