首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

小程序,容器中的指针地址到底是什么?该怎么解决

2012-02-07 
小程序,容器中的指针地址到底是什么? 程序如下:classObj{public:Obj(boolb){m_bAliveb}BOOLIsAlive(){re

小程序,容器中的指针地址到底是什么?

程序如下:

class   Obj
{
public:
Obj(   bool   b   )
{
m_bAlive   =   b;
}

BOOL   IsAlive()
{
return   m_bAlive;
}

private:
bool   m_bAlive;
};


list <   Obj*   >   arr;


void   del(   Obj*   &p   )
{
delete   p;
}

void   print(   Obj*   &p   )
{
if(   p   )
cout   < <   p   < <   "   ";
else
cout   < <   "00000000   ";
}

void   del_ptr(   Obj*   &p   )
{
if(   p-> IsAlive()   )
return;

delete   p;
}


void   func1()
{
arr.push_back(   new   Obj(   true   )   );
arr.push_back(   new   Obj(   true   )   );
arr.push_back(   new   Obj(   true   )   );
arr.push_back(   new   Obj(   false   )   );
arr.push_back(   new   Obj(   false   )   );


for_each(   arr.begin(),   arr.end(),   print   );
cout   < <   endl;

//   首先删除对象值为false的指针
for_each(   arr.begin(),   arr.end(),   del_ptr   );//(!问题!)

for_each(   arr.begin(),   arr.end(),   print   );
cout   < <   endl;


list <   Obj*   > ::iterator   _end;

//   然后删除迭代器
_end   =   remove(   arr.begin(),   arr.end(),   (Obj*)0   );
arr.erase(   _end,   arr.end()   );

for_each(   arr.begin(),   arr.end(),   print   );cout   < <   endl;

for_each(   arr.begin(),   arr.end(),   del   );
}

无论三个函数的参数是Obj*   p还是Obj*   &p,在for_each(   arr.begin(),   arr.end(),   del_ptr   )这一句都会出现问题,对象被删除了,但是下一次仍然能看到那个地址。

当然,可以通过下列方法实现:


list <   Obj*   > ::iterator   iter;

for(   iter   =   arr.begin();   iter   !=   arr.end();   )
{
if(   (   *iter   )-> IsAlive()   )
{
iter++;
continue;
}

delete   *iter;
*iter   =   0;
iter   =   arr.erase(   iter   );
}

那么通过算法传到函数中的地址显然并不是真正的对象地址,今早一个大牛同事也没解释出啥来,还请大家帮忙解释一下,谢谢!

[解决办法]
指针所指的内存被释放,但是指针所指的地址仍然不变,只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
[解决办法]
同意楼上意见.

对你的程序,包括那行.
// 首先删除对象值为false的指针
for_each( arr.begin(), arr.end(), del_ptr );//(!问题!)

内存被正确的释放乐, 但是指针所指的地址仍然不变,只是把指针所指的内存给释放掉,但并没有把指针本身干掉。

我用valgrind 查了一下内存, 没有leak.

[gx150-49]~/temp> valgrind --tool=memcheck --leak-check=yes ./a.out
==4978== Memcheck, a memory error detector for x86-linux.
==4978== Copyright (C) 2002-2005, and GNU GPL 'd, by Julian Seward et al.
==4978== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==4978== Copyright (C) 2000-2005, and GNU GPL 'd, by Julian Seward et al.
==4978== For more details, rerun with: -v
==4978==
0x1b92b028 0x1b92c368 0x1b92c3a0 0x1b92c3d8 0x1b92c410


==4978==
==4978== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 16 from 1)
==4978== malloc/free: in use at exit: 4461 bytes in 11 blocks.
==4978== malloc/free: 13 allocs, 2 frees, 4463 bytes allocated.
==4978== For counts of detected errors, rerun with: -v
==4978== searching for pointers to 11 not-freed blocks.
==4978== checked 106856 bytes.
==4978==
==4978== LEAK SUMMARY:
==4978== definitely lost: 0 bytes in 0 blocks.
==4978== possibly lost: 0 bytes in 0 blocks.
==4978== still reachable: 4461 bytes in 11 blocks.
==4978== suppressed: 0 bytes in 0 blocks.
==4978== Reachable blocks (those to which a pointer was found) are not shown.
==4978== To see them, rerun with: --show-reachable=yes
[解决办法]
void del_ptr( Obj* &p )
{
if( p-> IsAlive() )
return;

delete p;
}
这个改为
void del_ptr( Obj& *p )
{
if( p-> IsAlive() )
return;
delete p;
p = 0;
}
[解决办法]
delete p;
p = 0;

热点排行