为了账号安全,请及时绑定邮箱和手机立即绑定

到底应该怎么删除呢?真的不想搞到内存泄露。

到底应该怎么删除呢?真的不想搞到内存泄露。

呼如林 2023-04-22 10:06:07
最近在写A*算法,遇到一个问题,详细说来是这样的(源码太长我先说大概情况)声明: vector<TAStarNode *> openlist; 是一个指针的vector然后东西是这样放进去的:有一个大的循环{TAStarNode * p=NULL;while(!p)p = new TAStarNode[8];当然,接下来会给它们赋值。然后用一个循环把这8个都取址之后push_back进openlist里边。各种删除、修改处理}一直循环,也就是说,p指向的地址是不断改变的,而且中间还要用到那些点,没办法直接delete[] p。openlist中每个指针都只指向一个元素。所以我就放在最后在一个函数SafeDel()里边delete全部了。查了些资料之后是这样子写:iter=openlist.begin();for(;iter!=openlist.end();){delete *iter;iter=openlist.erase(iter);//erase会返回被删除迭代器后面那个}但是会卡住,调试发现是第一次执行到 delete *iter 就不会动了。另外,看了前面问的也试过这样for(int i=0;i<openlist.size();i++) delete openlist[i];结果也一样。在delete那里卡住走不下去,光标一直闪啊闪。源码太长,连剩下字数只够放头文件,所以就不发上来了
查看完整描述

3 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

p = new TAStarNode[8];
当然,接下来会给它们赋值。
然后用一个循环把这8个都取址之后push_back进openlist里边。
各种删除、修改处理

这个样子的话,只可以使用delete[] p,将所有分配的空间都释放掉。
这时如果delete (p+1),delete (p+2)。。。delete(p+7),都是
不对的,具体编译器会怎么处理这种情况,就不知道了。因为编译器“认为”
它没有分配(p+1)。
可以这么想:p=new xxx[8] 时,编译器将分配的内存的首地址和分配的字节数
存在了某个地方,以后删除的时候要从这里取回这些存储的信息,但是这里并
没有存储首地址为(p+1)。。。(p+7)的相关信息。就有可能删除出错。

后面的那些代码就是在删除(p+1)。。。(p+7)。
可以改作一次性删除delete[] 或者分配的内存时候单独分配。


查看完整回答
反对 回复 2023-04-25
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

p = new TAStarNode[8];
p是一个指针,指向一个TAStarNode数组。 你是想释放这里new的内存吧。
大的循环
{
TAStarNode * p=NULL;
while(!p)
p = new TAStarNode[8];
openlist.push_back(p);
}

最后时候,循环遍历删除即可。 
关于删除有2个选择:
vector<TAStarNode *>::iterator it = openlist.begin();
for(; it != openlist.end(); it++)
{
TAStarNode* p = it;
delete [] p;
p = NULL;
}
openlist.clear();

-----------------------------------
vector<TAStarNode *>::iterator it = openlist.begin();
for(; it != openlist.end(); it++)
{
TAStarNode* p = it;
delete [] p;
p = NULL;
openlist.erase(it);
it = openlist.begin();
}


查看完整回答
反对 回复 2023-04-25
?
慕森王

TA贡献1777条经验 获得超3个赞

你的动态内存申请了一份,你却释放了八次
你对动态内存的分配和释放的机制不理解。这是运行时错误。
你的这句代码“p= new TAStarNode[8];”其本质是这样的 从堆中分配 8*sizeof( TAStarNode)大小的内存,并且调用8次TASTarNode的构造函数,初始化你的动态内存。注意,分配内存是,相关的动态存储管理的数据结构(空闲链表或位图)记录了你申请的动态内存的首地址和大小。
而且,这片内存你再释放是只能释放一次,因为数据结构里就记录了这样一份首地址和大小。释放时,将自首地址起,连续的在数据结构中指定大小的内存归还给空闲存储区,然后调用析构函数。
我给你说一下delete和delete[]的区别,如果动态创建一个对象数组,用delete只能对数据中的第0个对象元素调用析构函数。其他不对象元素不可能调用。而delete[] 对所有数组中所有对象元素调用析构函数。如果你的数组中对象在创建时,其成员也是动态创建的,则用delete必然内存泄露。
你的这一句代码delete *iter;反复执行,多次释放动态内存,第二次循环时,必然错误。
如果你想编程进阶的话,不能只看编程书,操作系统,和数据结构必看。其实我就是当初看操作系统中动态存储管理,才理解这点的。

查看完整回答
反对 回复 2023-04-25
  • 3 回答
  • 0 关注
  • 83 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信