2016-03-30 25 views
0

不幸的是我現在面臨在我的課Valgrind的錯誤(無效讀取)的operator delete(void *的)從地圖中釋放對象時

==4442== Invalid read of size 4 
==4442== at 0x806EC34: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /home/blabla/projects/test proj) 
==4442== by 0x804C634: std::_Rb_tree_iterator<std::pair<std::string const, Order*> >::operator++(int) (stl_tree.h:197) 
==4442== by 0x804B98C: Play::~Play() (Play.cpp:46) 
==4442== by 0x80501AF: main (main.cpp:121) 
==4442== Address 0x421c5c4 is 12 bytes inside a block of size 24 free'd 
==4442== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==4442== by 0x8050D4E: operator delete(void*) (in /home/blabla/projects/test proj) 
==4442== by 0x804E1E6: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, Order*> > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, Order*> >*, unsigned int) (new_allocator.h:110) 
==4442== by 0x804DC59: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_put_node(std::_Rb_tree_node<std::pair<std::string const, Order*> >*) (stl_tree.h:374) 
==4442== by 0x804D2D7: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_destroy_node(std::_Rb_tree_node<std::pair<std::string const, Order*> >*) (stl_tree.h:422) 
==4442== by 0x804D3BB: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<std::string const, Order*> >) (stl_tree.h:1746) 
==4442== by 0x804CB9A: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<std::string const, Order*> >) (stl_tree.h:820) 
==4442== by 0x804C678: std::map<std::string, Order*, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<std::string const, Order*> >) (stl_map.h:697) 
==4442== by 0x804B96F: Play::~Play() (Play.cpp:50) 
==4442== by 0x80501AF: main (main.cpp:121) 
==4442== 
==4442== Invalid read of size 4 
==4442== at 0x806EC4B: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /home/blabla/projects/test proj) 
==4442== by 0x804C634: std::_Rb_tree_iterator<std::pair<std::string const, Order*> >::operator++(int) (stl_tree.h:197) 
==4442== by 0x804B98C: Play::~Play() (Play.cpp:46) 
==4442== by 0x80501AF: main (main.cpp:121) 
==4442== Address 0x421c5bc is 4 bytes inside a block of size 24 free'd 
==4442== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==4442== by 0x8050D4E: operator delete(void*) (in /home/blabla/projects/test proj) 
==4442== by 0x804E1E6: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, Order*> > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, Order*> >*, unsigned int) (new_allocator.h:110) 
==4442== by 0x804DC59: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_put_node(std::_Rb_tree_node<std::pair<std::string const, Order*> >*) (stl_tree.h:374) 
==4442== by 0x804D2D7: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_destroy_node(std::_Rb_tree_node<std::pair<std::string const, Order*> >*) (stl_tree.h:422) 
==4442== by 0x804D3BB: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<std::string const, Order*> >) (stl_tree.h:1746) 
==4442== by 0x804CB9A: std::_Rb_tree<std::string, std::pair<std::string const, Order*>, std::_Select1st<std::pair<std::string const, Order*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<std::string const, Order*> >) (stl_tree.h:820) 
==4442== by 0x804C678: std::map<std::string, Order*, std::less<std::string>, std::allocator<std::pair<std::string const, Order*> > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<std::string const, Order*> >) (stl_map.h:697) 
==4442== by 0x804B96F: Play::~Play() (Play.cpp:50) 
==4442== by 0x80501AF: main (main.cpp:121) 
==4442== 
==4442== 
==4442== HEAP SUMMARY: 
==4442==  in use at exit: 0 bytes in 0 blocks 
==4442== total heap usage: 34 allocs, 34 frees, 580 bytes allocated 
==4442== 
==4442== All heap blocks were freed -- no leaks are possible 
==4442== 
==4442== For counts of detected and suppressed errors, rerun with: -v 
==4442== ERROR SUMMARY: 11 errors from 2 contexts (suppressed: 0 from 0) 

那地方的一個這個問題,我現在面臨這個問題在析構函數

std::map<std::string, Order*>::iterator order_itr; 
for(ord_itr = order_.begin(); ord_itr != order_.end(); ord_itr++) 
{ 
    //if(ord_itr->second != nullptr) 
    delete ord_itr->second; 
    order_.erase(ord_itr); 
} 

釋放分配的內存時,從上面的迭代器,你可以用什麼樣的std ::的地圖我處理看到的。正如你所看到的,我甚至試圖檢查它是否爲空指針而不是釋放它(沒有任何意義,因爲它們都應該被分配)

而對於最後,這是我的構造函數,我分配內存

order_["test1"] = new Test1Order(); 
order_["test2"] = new Test2Order(); 
order_["test3"] = new Test3Order(); 
order_["test4"] = new Test4Order(); 
order_["test5"] = new Test5Order(); 
order_["test6"] = new Test6Order(); 
order_["test7"] = new Test7Order(); 

感謝

回答

1

每當我們通過遍歷地圖和擦除的迭代器指向的元素,你必須繼續與擦除返回的迭代循環:

std::map<std::string, Order*>::iterator order_itr = order_.begin(); 
while(ord_itr != order_.end()) 
{ 
    delete ord_itr->second; 
    ord_itr = order_.erase(ord_itr); 
} 

但是,這可能是更加透明:

std::map<std::string, Order*>::iterator order_itr; 
for(ord_itr = order_.begin(); ord_itr != order_.end(); ord_itr++) 
    delete ord_itr->second; 
order_.clear(); 

或基於一定範圍(C++ 11):

for(const auto& key_value : order_) 
    delete key_value.second; 
order_.clear(); 
+0

沒有人提到,這裏http://stackoverflow.com/questions/19970531 /妥善摧毀指針在一個stdmap 無論如何,完美,謝謝!我還有一個問題。在你的第一個方法之後,我遇到了一個內存泄漏,實際上沒有發生(order_.clear())的方法。你碰巧有什麼想法爲什麼? 這是錯誤信息http://pastebin.com/8YAM2TuK –

+0

@JohnnieW不,這取決於你的調試。 –

+0

你剛纔向我展示了兩種方式來完成同樣的事情,爲什麼它會有所不同,然後O.o根本沒有意義 –