我尝试释放由STL列表的指针项指向的内存。
这应该可以正常工作但在我的情况下,列表中可能有重复的指针,我得到一个双dealloc异常,即使我测试指针是否为NULL(参见下面的源代码)。 我该如何解决这个问题?
list<Line *> * l = new list<Line *>;
Line * line = new Line(10, 10, 10, 10);
l->push_back(line);
l->push_back(line);
cout << "line addr " << line << endl;
for (list<Line *>::iterator it = l->begin(); it != l->end(); it++)
{
if (*it != NULL)
{
cout << "line it " << *it << " " << (*it)->toString() << endl;
delete (*it);
(*it) = NULL;
}
}
l->clear();
*** glibc detected *** /home/debian/workspace/Scrap/Release/Scrap: double free or corruption (!prev): 0x0846de20 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6[0xb6d68764]
/lib/i686/cmov/libc.so.6(cfree+0x96)[0xb6d6a966]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb6f402e1]
/home/debian/workspace/Scrap/Release/Scrap[0x8067cb0]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb6d10455]
/home/debian/workspace/Scrap/Release/Scrap(_ZNSt8ios_base4InitD1Ev+0x49)[0x8052cd1]
======= Memory map: ========
08048000-0842c000 r-xp 00000000 08:01 3819374 /home/debian/workspace/Scrap/Release/Scrap
0842c000-08451000 rw-p 003e3000 08:01 3819374 /home/debian/workspace/Scrap/Release/Scrap
答案 0 :(得分:5)
你能使用智能指针而不是原始指针吗?我会尝试使用boost shared_ptrs,如下所示:
#include <boost/shared_ptr.hpp>
list< boost::shared_ptr< Line > > l;
boost::shared_ptr< Line > line( new Line( 10, 10, 10, 10 ) );
l.push_back( line );
l.push_back( line );
当列表被销毁时,boost::shared_ptr
清理将删除Line
个对象。
答案 1 :(得分:4)
l->push_back(line);
l->push_back(line);
这只会插入两个指向同一参考的指针。
delete (*it);
因此,当您为第1行调用此时,原始行将丢失。第二行现在指向一个解除分配的对象。
为什么不使用list<Line>
(没有指针)?这样可以完全避免new
/ delete
问题,但代价是存储按值。
或使用@Edric's answer中的shared_ptr
。
答案 2 :(得分:1)
你可以创建临时的std :: set,用原始容器的项目填充它,并删除循环中的所有set项目(设置保证我们只有唯一的项目)。
或者您可以将std :: unique函数应用于容器
但我建议你使用智能指针(类似于boost :: shared_ptr)。他们将完成有关内存管理的所有工作。
答案 3 :(得分:0)
您只创建一个线对象(只有一个新对象)
但是你要删除它两次,因为你把同一个对象放到列表中两次。
执行:
Line * line = new Line(10, 10, 10, 10);
l->push_back(line);
line = new Line(10, 10, 10, 10); // second new
l->push_back(line);
答案 4 :(得分:0)
行已分配一次,但会在列表中添加两次。第一次删除将释放分配的内存。第二次删除会抱怨它。这是完全正常的。
考虑使用例如引用计数的智能指针而不是普通指针。