2017-02-26 60 views
1

我正在用C++寫一個服務器。我使用std :: set容器來保存一個訪問所有客戶端內存對象的指針。我使用valgrind來檢查我是否沒有任何內存泄漏。第一次使用我的套裝時,我閱讀無效。我寫了一些代碼來解釋我的問題。C++ std :: set插入無效讀取

#include <iostream> 
#include <set> 

using namespace std; 

int main() { 
    set<int> s; 

    s.insert(1); 
    s.insert(2); 
    s.insert(3); 

    for (auto it = s.begin(); it != s.end(); it++) { 
    cout << "Data:" << *it << endl; 
    s.erase(it); 
    } 

    return 0; 
} 

我用這些標誌進行編譯,然後用valgrind啓動我的程序。

g++ -ggdb -std=c++17 set.cpp && valgrind ./a.out' 

此代碼產生 「大小爲8的無效讀」 到的std :: _ Rb_tree_increment(STD :: _ Rb_tree_node_base常量*)(以/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0。 21)

這不是來自我的代碼,所以我可以解決這個問題?

對不起,我的英語,我學習它...

回答

3

it是無效的,你刪除它後,卻erase返回最後刪除元素之後的迭代器,從而可以循環切換到

for (auto it = s.begin(); it != s.end();) { 
    cout << "Data:" << *it << endl; 
    it = s.erase(it); 
} 
+0

謝謝,我在想這個問題是由於插入方法或許多線程試圖在同一時間訪問該集合...我只是添加一個互斥鎖來鎖定元素,當我改變它和我的服務器工作完美。 – olive007

3

一旦你調用s.erase(it),迭代器it不再有效。任何對迭代器的引用(如it++)都是未定義的行爲。

it++調用std::_Rb_tree_increment的調用中看起來像增加了it,此時處於無效狀態。 Valgrind檢測到這種情況,並報告無效的讀取。

+0

但它返回一個迭代器的下一個元素,所以它可能是通過使用和固定'it ++'只有在沒有任何東西被擦除時才被修復 – user463035818