unique_ptr是否按预期正确使用?代码以一些内存泄漏(可能是误报?或真正的泄漏?)结束。我想将所有权移到RunSimulation,其中unique_ptr的生命将结束,并且在循环中将创建更新的生命,但是,这将以访问冲突结束。
理想情况下,我希望main()中的一个unique_ptr对象在main()中到期,另一个在main外部发送,以便在RunSimulation()中释放。
class Result { public: int n; };
void RunSimulation(std::unique_ptr<Result> result) {result->n = 0;}
void main()
{
boost::thread_group threads;
std::unique_ptr<Result> r;
std::unique_ptr<Simulation> sim = std::make_unique<Simulation>();
for (int i = 0; i < 10; i++)
{
r = std::unique_ptr<Result>(new Result);
//Erroneous lines:
//threads.create_thread(boost::bind(&RunSimulation, std::move(r)));
//threads.create_thread([&] {RunSimulation(std::move(r)); });
}
threads.join_all();
}
答案 0 :(得分:2)
您没有内存泄漏,但这并不是说您的代码是正确的。看看你的循环:
all_keys = list()
...
all_keys += list(set(reader.fieldnames).difference(set(all_keys)))
每次将新的Result实例分配给r时,旧的Result实例都会被unique_ptr删除。这可能发生在其指针使用它的线程之前,在这种情况下,您尝试取消引用已删除的内存。这是未定义的行为。
<强>更新强> 这是一个例子
for (int i = 0; i < 10; i++)
{
r = std::unique_ptr<Result>(new Result);
threads.create_thread([&] { RunSimulation(r.get()); });
}
答案 1 :(得分:0)
在下面正确使用unique_ptr
没有
r
指向的对象在连续迭代中被破坏,而它仍然可以在复制指针的线程中使用,从而导致未定义的行为。
代码以一些内存泄漏结束(可能是误报?
可能。在_CrtDumpMemoryLeaks
被销毁之前调用r
,因此内存尚未被释放。
我认为将所有权移至RunSimulation,其中unique_ptr的生命将结束
这是一个明智的想法。我建议这样做。
然而,以访问冲突结束。
那个程序可能也有错误。
for (int i = 0; i < 10; i++)
{
r = std::unique_ptr<Result>(new Result);
threads.create_thread([&] { RunGridSimulation(std::move(r)); });
}
这个替代方案的问题(好的,同样的问题也在最初的替代方案中)是你捕获对局部变量的引用,但是在超出局部变量范围的线程中使用lambda。所有线程都将指向同一个变量,如果线程没有碰巧与循环完美交错,那么一个线程将从另一个线程已经移动的唯一指针移动,导致指针未定义时的行为解除引用。
您必须将唯一指针移动到lambda中,而不是通过引用捕获它。