C++ 将std::线程分配给向量时出现SEGFULT<;标准:螺纹>;

C++ 将std::线程分配给向量时出现SEGFULT<;标准:螺纹>;,c++,multithreading,c++11,segmentation-fault,C++,Multithreading,C++11,Segmentation Fault,这是一个错误: std::vector<std::thread> _pool; State & _state; ... for(uint32_t n = 0; n < nThreads; ++n) _pool[n] = std::thread(_thFunction, std::ref(_state)); std::vector\u池; 州和州; ... 对于(uint32_t n=0;n

这是一个错误:

std::vector<std::thread>    _pool;
State &                     _state;

...

for(uint32_t n = 0; n < nThreads; ++n)
    _pool[n]  = std::thread(_thFunction, std::ref(_state));
std::vector\u池;
州和州;
...
对于(uint32_t n=0;n
这并不是:

std::vector<std::thread>    _pool;
State &                     _state;

...

for(uint32_t n = 0; n < nThreads; ++n)
    _pool.push_back( std::thread(_thFunction, std::ref(_state)) );
std::vector\u池;
州和州;
...
对于(uint32_t n=0;n
使用push_返回向量而不是对向量中的特定条目赋值的区别

_thFunction是一个std::函数

当我对第一个代码块应用pool.reserve(10)时,在第一次赋值时仍然会得到一个segfault

我怀疑这与移动语义有关,但我不确定。这是怎么回事

来自gdb的stacktrace似乎表示此指针为空:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004092e5 in std::thread::joinable (this=0x0) at /usr/include/c++/4.8.3/thread:162
162     { return !(_M_id == id()); }
(gdb) backtrace
#0  0x00000000004092e5 in std::thread::joinable (this=0x0) at /usr/include/c++/4.8.3/thread:162
#1  0x000000000040927a in std::thread::operator=(std::thread&&) (this=0x0, 
    __t=<unknown type in /home/stackuser/src/dsl/build/debug/server/dsl, CU 0x0, DIE 0x37b88>)
    at /usr/include/c++/4.8.3/thread:150
#2  0x000000000041350d in ThreadPool<std::function<void (State&)> >::ThreadPool(State&, unsigned int, std::function<void (State&)>) (this=0x69aed0, state=..., nThreads=2, thFunction=...)
    at src/server/ThreadPool.h:38
#3  0x0000000000408405 in Application::Application (this=0x6946e0) at src/server/Application.cpp:69
#4  0x0000000000455594 in Singleton<Application>::CreateInstance () at src/server/Singleton.h:12
#5  0x0000000000454997 in main (argc=1, argv=0x7fffffffdc98) at src/server/main.cpp:85
程序接收信号SIGSEGV,分段故障。
std::thread::joinable(this=0x0)at/usr/include/c++/4.8.3/thread:162中的0x00000000004092e5
162{return!(_M_id==id());}
(gdb)回溯
#std::thread::joinable(this=0x0)at/usr/include/c++/4.8.3/thread:162中的0 0x00000000004092e5
#在std::thread::operator=(std::thread&&)(this=0x0,
__t=)
at/usr/include/c++/4.8.3/thread:150
#ThreadPool::ThreadPool中的2 0x000000000041350d(状态和,无符号int,std::function)(this=0x69aed0,状态=…,nThreads=2,thFunction=…)
在src/server/ThreadPool.h:38
#src/server/Application.cpp:69处的Application::Application(this=0x6946e0)中的3 0x000000000040405
#src/server/Singleton.h:12处Singleton::CreateInstance()中的4 0x000000000045594
#5 0x0000000000454997位于src/server/main的main中(argc=1,argv=0x7fffffffdc98)。cpp:85
阅读您正在使用的
运算符[]
的参考

返回对指定位置处元素的引用。不执行边界检查

因此,当您在一个空向量上调用
\u pool[n]
时,您会得到一个对不存在的对象的引用,随后会出现未定义的行为。为该引用赋值不会使向量增长

reserve
也不会向向量添加任何元素。它只是增加了向量的容量,这意味着在最后插入元素不会使元素的迭代器/引用/指针失效,直到达到该容量为止

resize(n)
将在向量中创建
n
对象,我怀疑您希望
reserve
这样做,当您不知道构建向量时的计数和值时,这是使用相同对象初始化向量的最佳方法。但是,如果无论如何都要覆盖对象,
push_back
reserve
将浪费更少的资源。或者,如果您知道要在向量中输入的值,只需使用构造函数填充向量。

读取您正在使用的
运算符[]
的引用

返回对指定位置处元素的引用。不执行边界检查

因此,当您在一个空向量上调用
\u pool[n]
时,您会得到一个对不存在的对象的引用,随后会出现未定义的行为。为该引用赋值不会使向量增长

reserve
也不会向向量添加任何元素。它只是增加了向量的容量,这意味着在最后插入元素不会使元素的迭代器/引用/指针失效,直到达到该容量为止


resize(n)
将在向量中创建
n
对象,我怀疑您希望
reserve
这样做,当您不知道构建向量时的计数和值时,这是使用相同对象初始化向量的最佳方法。但是,如果无论如何都要覆盖对象,
push_back
reserve
将浪费更少的资源。或者,如果您知道向量中需要的值,您可以使用构造函数简单地填充向量。

这与移动语义无关,您只是尝试将不存在的向量元素赋值

\u pool.push_back()
创建新元素,但
\u pool[n]
不创建新元素

reserve()


要么调整向量的大小,使元素在分配给它们之前存在,要么使用
推回

它与移动语义无关,您只是试图分配给不存在的向量元素

\u pool.push_back()
创建新元素,但
\u pool[n]
不创建新元素

reserve()


调整向量大小,使元素在分配给它们之前存在,或者使用
向后推
std::vector::reserve
将仅“准备”向量以增长,但向量的逻辑大小仍然为0<代码>因此_pool[n]=…
仍然无效。您应该改用
std::vector:resize

std::vector::reserve
只会“准备”要增长的向量,但向量的逻辑大小仍然为0<代码>因此_pool[n]=…
仍然无效。您应该改用
std::vector:resize

使用
reserve()
不会创建任何元素-它只确保在创建元素时不会执行分配。创建包含10个空元素的向量,如下所示:

std::vector<std::thread>    _pool(10);
std::vector_池(10);
您的第一个示例将使用
reserve()
工作,它不创建任何元素-它只确保在创建元素时,不会执行分配。创建向量