每当我使用线程执行以下代码时,程序都会出现此错误:
调试错误! 程序:... / path/to/.exe
abort()被称为
我想创建一个调用成员函数的线程。这是我正在使用的功能:
void ServerVote::createConnexionThreads()
{
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads.push_back(&(std::thread(&ServerVote::acceptConnection,*this, i)));
}
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads[i]->join();
}
}
如果需要,我可以提供额外的代码。使用调试器时,我发现在线程被push_back之后,程序在创建第一个线程后立即崩溃。然后调用~thread()并在此函数内崩溃。这是矢量声明:
std::vector<std::thread*> m_connexionThreads;
我正在使用Visual Studio 2015.acceptConnection函数在其中有一段时间(true),并计划稍后终止。
编辑:
感谢您的回答,但在使用线程对象而不是指针时无法编译。所以,当我试图进入这个载体时:
std::vector<std::thread> m_connexionThreads;
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads.push_back((std::thread(&ServerVote::acceptConnection,*this, i)));
}
编译时出现此错误:
error C2280: 'std::thread::thread(const std::thread &)': attempting to reference a deleted function
答案 0 :(得分:3)
您不应尝试在任何上下文中使用临时地址。事实上,这是MSVC中允许此代码的错误。任何符合标准的编译器都会在这里产生错误。
相反,您应该使用这样的线程对象(请参阅我的编辑下面的代码,了解为什么这是首选):
#include <thread>
#include <vector>
void acceptConnection(int);
void foo() {
std::vector<std::thread> vec;
for (int i = 0; i <= 50; ++i)
vec.push_back(std::thread(acceptConnection, i));
}
为什么这种方法比使用分配指向线程对象的指针更受欢迎?有很多好处:
unique_ptr
来确保自动清理内存 - 这使语法更加丑陋!答案 1 :(得分:2)
您正在堆栈中创建一个本地线程实例,获取其地址并将其推送到向量。线程对象将在方法退出时被删除,因此您将留下指向已删除对象的指针。
您应该使用new
在堆中创建线程对象,以便在方法退出时不会删除它,或者不使用指向线程对象的指针。