簡體   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