2017-02-13 63 views
2
#include <vector> 
#include <string> 
#include <mutex> 
#include <future> 

using namespace std; 

mutex g_mtx; 
vector<string> g_coll; 

void Cleaner() 
{ 
    lock_guard<mutex> lock(g_mtx); 
    g_coll.clear(); 
} 

const vector<string>& Getter() 
{ 
    lock_guard<mutex> lock(g_mtx); 
    return g_coll; 
} 

int main() 
{ 
    g_coll = { "hello" }; 
    auto fut = async([&]() 
    { 
     Cleaner(); 
    }); 

    auto returned_coll = Getter(); 
    fut.get(); 
} 

如果Cleanerreturn g_coll;後執行,不C++標準保證returned_coll包含{ "hello" }以「std :: lock_guard <mutex>」作爲參考返回共享對象是否安全?

回答

5

不,這不安全。

在語義上,當非void返回類型返回的函數是活動的順序如下:

  1. 在返回語句中的表達式求值。
  2. 返回值從所述表達式複製初始化。
  3. 自動局部變量以相反的構造順序銷燬。
  4. 控制權返回給調用者。

請注意,returned_coll不是返回值。相反,Getter()是返回值。的returned_collGetter()返回左值初始化步驟後,會出現4

因此,當returned_coll是複製初始化從Getter(),由Getter舉行的互斥量已經被釋放,這意味着returned_coll初始化可能與種族在Cleaner訪問。

相關問題