繁体   English   中英

将std :: thread分配给向量时出现segfault <std::thread>

[英]segfault when assigning an std::thread to a vector<std::thread>

此段错误:

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

阅读您正在使用的operator[]参考文档

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

因此,当您在空向量上调用_pool[n]时,将获得对不存在对象的引用,从而导致未定义的行为。 给该参考分配一个值不会使向量增长。

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

resize(n)会在向量中创建n对象,我怀疑您希望reserve该对象,这是在不知道构造向量时的计数和值的情况下用相同对象初始化向量的好方法。 但是,如果仍然要覆盖对象,则使用reserve push_back会浪费更少的资源。 或者,如果您知道向量中想要的值,则可以使用构造函数简单地填充向量。

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

_pool.push_back()创建一个新元素,但_pool[n]没有。

reserve()也不创建元素,它只是为它们分配内存(但不构造它们)

resize向量的resize以使元素存在,然后再分配给它们,或者使用push_back

std::vector::reserve只会“准备”向量增长,但是向量的逻辑大小仍然为0。 So _pool[n] = ...仍然无效。 您应该改用std::vector:resize

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

std::vector<std::thread>    _pool(10);

你的第一个例子将工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM