【问题标题】:C++ returning an rvalue doesn't work and segfault [duplicate]C++ 返回右值不起作用和段错误[重复]
【发布时间】:2022-12-10 22:19:18
【问题描述】:

我有一个函数可以创建一个向量,用它做一些事情然后将它作为一个返回右值使用std::move。 当我将它分配给一个变量时,我期望调用std::vector的移动构造函数std::vector::vector(vector&&)。 但是我遇到了分段错误。

这是我的代码:

#include <iostream>
#include <vector>

std::vector<int>&& getVector(int start)
{
    auto result = std::vector<int>();
    result.reserve(10);
    for (int i = start; i < start + 10; i++)
        result.push_back(i);
    return std::move(result);
}

int main()
{
    std::cout << "Did I break here 1" << std::endl;
    auto vec = getVector(10);
    std::cout << "Did I break here 2" << std::endl;
}

它给了我

Did I break here 1
[1]    55419 segmentation fault <executable_file>

我只是猜测移动构造函数或右值有问题。顺便说一句,我返回一个右值来不复制向量的值并窃取指向它的指针。

【问题讨论】:

  • 我不明白你打算如何让它工作,或者你打算如何让调用代码工作。为什么不按价值回报呢?
  • 按值返回它会在调用者的范围内构造另一个向量并复制数据,对吗?
  • @JasonLiam 我使用 -Wall -Wextra -Wpedantic 和 clang++。它不是引用,因为它是右值
  • @Sisyffe 看到 gcc 给出警告 here

标签: c++ c++11 vector segmentation-fault


【解决方案1】:

您正在返回对局部变量 result 的引用。该对象在函数返回之前被销毁,然后您尝试从悬空引用移动构造 vec

您不需要在 return 语句中显式返回右值引用或 std::move 以获得移动语义。你应该做直截了当的事情:

std::vector<int> getVector(int start)
{
    auto result = std::vector<int>();
    //...
    return result;
}

//...

auto vec = getVector(10);

现在 vec 将从 result 移动构造,甚至可以省略构造函数调用。在 C++17 之前,如果编译器没有优化,可能会有三个(包括= std::vector&lt;int&gt;())移动构造函数调用。从 C++17 开始,最多只有一个。在任何情况下都不会有任何复制构造函数调用。

【讨论】:

  • 那么auto vec = getVector(10) 会自动调用移动构造函数而不是复制构造函数吗?
猜你喜欢
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 2014-09-24
相关资源
最近更新 更多