2016-09-01 10 views
0

これはなぜ未定義の動作ですか?ベクトル上にEmplaceバックスレッド

スレッドをコメント行のように作成すると、そのスレッドはコピー/移動された割り当てなので、スレッドを作成するときにはうまくいかないのはなぜですか?

+0

「動作しない」と「未定義の動作」についてより具体的にしてください。 また、オブジェクトをインプレースで作成するには、threads.emplace_back(task)を実行する必要があります。 – Dmitry

+1

参加しようとしているスレッドは参加できません。 C++の一般的なアドバイスは、いつものように、もっと複雑なことをする前に* 'int'と' std :: vector 'を完全に理解していることを確認することです。それらがあなたに完全にはっきりしていて、問題があるときは、まずそれを 'int'か' std :: vector 'に減らしてください。 –

答えて

4

コードでは、3つのデフォルトスレッドを構築してから、他の3つのスレッドを追加しています。

変更:

std::vector<std::thread> threads; 
const size_t number_of_threads=3; 

int main(){ 
    threads.reserve(number_of_threads); 
    spawn(); 
} 

そして spwan内側:

std::vector<std::thread> threads(3); 

void spawn() { 
    for(int i=0; i<number_of_threads; ++i){ 
     threads.emplace_back(std::thread(task)); 
    } 
    for(int i=0; i<threads.size(); ++i){ 
     threads[i].join(); 
    } 
} 

あなたがemplace_backpsuh_backを使用している、あなたが前にメモリを割り当ててはいけません。ちょうどreserveです。

あなたが直接書き込むことができますemplace_backないpush_backを使用しているので、ところで、:

threads.emplace_back(task); 
+0

容量を予約しても、threads.size()はまだ0を返し、threads.capacity()は任意の数> = 3を返すことに注意してください。したがって、spawn()の最初のループは同じ値同じ変数または定数)がreserve()に渡されます。この特定のケースでは、reserve()を呼び出すことでおそらく何も得られません。 – Jeremy

+0

あなたは私が見逃した最初の部分について正しいです。しかし、実際に起こる可能性のある再割り当てを拒否する予約を使用することによる利益が実際にあります。 –

+1

インプリメンテーションが、あなたが予約したサイズよりも小さいインクリメントでベクトルを成長させる場合のみ - この特定のケースでは非常に起こりそうなことはありません。 – Jeremy

関連する問題