我在这段代码中有泄漏。我知道我将对象传递给向量和lambda函数不正确,但我不确定如何解决这个问题。你能否给我任何代码审查和更正?
std::vector<std::thread> threads;
std::vector<std::unique_ptr<FileHandler>> fileHandlers;
for (std::string argument : filesToParse)
{
std::unique_ptr<FileHandler> fileHandler(new FileHandler(argument));
fileHandlers.push_back(std::move(fileHandler));
threads.push_back(std::thread([&fileHandler]()
{
fileHandler->processFile();
}));
}
for(auto i = 0; i < threads.size(); ++i)
{
threads.at(i).join();
fileHandlers.at(i)->mergeMaps(finalMap);
}
答案 0 :(得分:2)
显示的逻辑有几个问题。
fileHandlers.push_back(std::move(fileHandler));
fileHandler
unique_ptr的内容已移至此处。紧接着:
threads.push_back(std::thread([&fileHandler]() {
这会向每个新主题传递对其内容刚刚离开的unique_ptr
的引用。这个unique_ptr
已经去见了它的制造者。它不复存在。加入合唱团看不见。这是前任unique_ptr
。
fileHandlers.push_back(std::move(fileHandler));
回到此声明。在这里,你得到一个价格为两个逻辑错误。
fileHandlers
是一个向量。向向量添加值可以重新分配向量。重新分配使所有现有的迭代器,指针或对向量的现有内容的引用无效。传递对此向量中某些内容的引用,然后在循环的下一次迭代中向该向量添加一些内容,如果向量重新分配,则会在您的脸上爆炸。
这里显而易见的意图是使用所有线程的所有参数列表填充fileHandlers
向量。有两种基本方法可以正确完成:
使用reserve()
确保不会再发生重新分配。
首先使用所有值填充向量,然后仅生成所有线程,向每个线程传递对现在完整向量中自己的参数的引用。
您有几种方法可以解决这些问题:
首先填充向量,或保留其内容,然后传递给不是fileHandler
unique_ptr的每个线程,而是传递给unique_ptr
数组中的fileHandlers
已经填充。
或者,可以通过切换到shared_ptr
并通过值 <捕获 来提前预留或填充向量/ strong>每个帖子的shared_ptr
参数。