gpt4 book ai didi

c++ - 从 map 中释放对象时出现 Valgrind 错误(无效读取)运算符删除(无效*)

转载 作者:行者123 更新时间:2023-11-28 05:45:29 25 4
gpt4 key购买 nike

不幸的是,我在我的一个类(class)中遇到了这个问题

==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::map。正如你所看到的,我什至试图检查它是否是一个空指针而不是释放它(这没有意义,因为它们都应该被分配)

最后,这是我分配内存的构造函数

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();

谢谢

最佳答案

每当您遍历 map 并删除迭代器指向的元素时,您必须使用删除返回的迭代器继续循环:

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();

关于c++ - 从 map 中释放对象时出现 Valgrind 错误(无效读取)运算符删除(无效*),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36316874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com