这段错误:
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<std::thread> _pool;
State & _state;
...
for(uint32_t n = 0; n < nThreads; ++n)
_pool.push_back( std::thread(_thFunction, std::ref(_state)) );
使用push_back与向量的区别,而不是使用赋值给向量中的特定条目。
_thFunction是一个std :: function。
当我将pool.reserve(10)应用于第一个代码块时,我仍然会在第一个分配时遇到段错误。
我怀疑这与移动语义有关,但我不确定。这是怎么回事?
来自gdb的stacktrace似乎表示null这个指针:
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
答案 0 :(得分:3)
阅读您正在使用的operator[]
的参考documentation。
返回对指定位置pos处元素的引用。没有进行边界检查。
因此,当您在空向量上调用_pool[n]
时,您将获得对不存在的对象的引用,并且随后会出现未定义的行为。为此引用赋值不会使向量增长。
reserve
也不会向矢量添加任何元素。它只是增加了向量的容量,这意味着向元素插入元素不会使元素的迭代器/引用/指针无效,直到达到该容量。
resize(n)
会在向量中创建n
个对象,我怀疑你期待reserve
这样做,并且当你做的时候,用相同的对象初始化向量是很好的方法#39;知道构造向量时的计数和值。但是如果您要覆盖对象,push_back
reserve
会浪费更少的资源。或者,如果您知道向量中需要的值,则可以使用构造函数填充向量。
答案 1 :(得分:2)
它与移动语义无关,你只是试图分配给不存在的向量元素。
_pool.push_back()
会创建一个新元素,但_pool[n]
不会。
reserve()
也没有创建元素,它只为它们分配内存(但不构造它们)
向量resize
向量,以便在分配元素之前存在元素,或使用push_back
答案 2 :(得分:2)
std::vector::reserve
只会“准备”向量增长,但向量的逻辑大小仍为0. So _pool[n] = ...
仍然无效。您应该使用std::vector:resize
代替。
答案 3 :(得分:1)
使用reserve()
不会创建任何元素 - 它只会确保在您创建它们时,不会执行任何分配。使用10个空元素创建向量:
std::vector<std::thread> _pool(10);
并且您的第一个示例将起作用