Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 线程中的清理(使用delete)失败_C++_Multithreading_C++17 - Fatal编程技术网

C++ 线程中的清理(使用delete)失败

C++ 线程中的清理(使用delete)失败,c++,multithreading,c++17,C++,Multithreading,C++17,为什么在线程中使用delete会失败,但如果同步调用则不会 class dummyclass{}; main() { vector<dummyclass*> testlist{}; for(int i=0; i<5; i++) { auto value = new dummyclass(); testlist.push_back(value); } thread cleanuptest([&]()

为什么在线程中使用delete会失败,但如果同步调用则不会

class dummyclass{};

main()
{
    vector<dummyclass*> testlist{};
    for(int i=0; i<5; i++)
    {
        auto value = new dummyclass();
        testlist.push_back(value);
    }
    thread cleanuptest([&]() {for (auto x : testlist) delete x;}); // fails (abort())
}
编辑/评论

分离和连接是正确的解决方案

在main实际上是一个更大的程序中的一个方法的情况下,detach是有趣的


在单元测试的情况下,在类的析构函数中调用join进行测试会更干净。

在线程有机会完成之前,main已经完成,这导致了中止。您应该进行清理测试。加入线程,让它在主线程退出之前完成。

您的主线程在线程有机会完成之前完成,这将导致中止。您应该cleanuptest.join线程,让它在主退出之前完成。

程序的问题是,您的主函数在cleanuptest线程有机会运行到完成之前退出,并将testlist对象带走。因此,当cleanuptest运行时,它可能会尝试访问一个已经被破坏或正在被破坏的向量,这取决于线程执行的时间;它们彼此异步运行,因此它们的相对时间是不确定的

另一个可能是中止调用源的问题是,std::thread析构函数检测到您正在销毁thread对象,而没有首先对其调用join或detach,这是错误的

修复很简单,只需将这一行添加到main的底部:


join方法在子线程退出之前不会返回,因此它将保证testlist在子线程使用完之前保持有效。

程序的问题是,在cleanutest线程有机会运行完成之前,您的主函数退出,并带走testlist对象。因此,当cleanuptest运行时,它可能会尝试访问一个已经被破坏或正在被破坏的向量,这取决于线程执行的时间;它们彼此异步运行,因此它们的相对时间是不确定的

另一个可能是中止调用源的问题是,std::thread析构函数检测到您正在销毁thread对象,而没有首先对其调用join或detach,这是错误的

修复很简单,只需将这一行添加到main的底部:


join方法在子线程退出之前不会返回,因此它将保证testlist在子线程使用完毕之前保持有效。

在继续之前,您可能需要cleanuptest.join。如果在程序继续运行或被强制终止之前,线程未能删除所有内存,该怎么办?在继续运行之前,您可能需要cleanuptest.join。如果在程序继续运行或被强制终止之前,线程未能删除所有内存,该怎么办?现在,也就是说,创建一个线程cleanuptest,然后立即调用cleanuptest.join,这与直接在main中调用底层函数而不使用任何线程并没有太大的区别,创建一个线程cleanuptest,然后立即调用cleanuptest.join,这与直接在main中调用底层函数而不使用任何线程并没有很大区别。
cleanuptest.join();