【发布时间】:2019-09-20 05:17:29
【问题描述】:
此代码创建并执行一个线程,该线程需要获取std::list<int> data 的内容,而不会复制此列表的内容并将其地址更改为内存。指向列表的指针必须对其他代码保持有效。
线程创建后,原来的列表data在主线程中被销毁,所以在这种情况下我不能使用它的地址。
我怎样才能做到这一点?我尝试过使用右值引用,但我担心如果我以这种方式尝试它可能会有一个悬空指针。这是我所拥有的:
void func(std::list<int> && data){ // <-- what should go here as an argument?
std::sort(data.begin(), data.end());
// do stuff with data
}
int main(){
{
std::list<int> data;
data.push_back(1);
std::thread(func, std::move(data)).detach();
}
// data destroyed
}
【问题讨论】:
-
如果这会导致内存损坏,我会感到非常惊讶。不过,您为什么要通过引用接受?除了让人们(包括你自己)感到困惑之外,没有其他理由。如果您使用 std::reference_wrapper 将列表从 main() 传递给线程,那只会是内存损坏
-
@arne - 我将列表的内容保持在同一地址(其他代码保持指向它们的指针必须保持有效),所以我必须避免复制。我希望通过右值传递显式避免复制,而通过值传递允许复制。
-
抱歉,我不确定你的意思。这里永远不会复制向量的内容,只是交换来自 std::list 的原始指针。然而 main() 中的原始列表现在是空的,那么为什么要保留对它的引用呢?在上面的示例中,func() 传递了来自 std::thread 内容的引用,而不是 main() 内部变量的引用。正如我所说,您需要 std::reference_wrapper 将真正的引用传递给线程。
-
@ArneJ - 很抱歉造成混乱,我已经重写了问题以扩大并希望澄清问题
-
不会有悬空引用,数据本身也不会移动(参见 std::list 的引用)
标签: c++ multithreading rvalue