标题:内存释放问题
只看楼主
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
 问题点数:0 回复次数:13 
内存释放问题
在 C# 语言里,只有为某个对象申请内存空间的new ,而没有对应的delete,因为C#把释放内存的工作交给了系统,而系统一般只是在这个程序运行 结束时才一次性的把分配给他的堆内存全部回收,而程序本省不能直接释放某个对象的 堆内存。但是C/C++里有free/delete,这是否意味着某次调用这些函数的时候系统就将执行堆内存的回收?
搜索更多相关主题的帖子: 堆内存 回收 释放 对象 
2008-08-08 09:54
xzx1002002
Rank: 2
等 级:论坛游民
帖 子:68
专家分:27
注 册:2006-3-7
得分:0 
期待标准答案。。。。。
2008-08-08 12:56
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
1.首先就C#而言,确实对于大多数程序来说,并不需要程序员自己来管理堆内存,因为C#有很好的"垃圾回收"机制,但是这种垃圾回收机制的代价是非常大的,这一点需要明确.
2.其次,并且一定要等到程序退出,才进行垃圾回收,当你的程序空间不足时,系统为自动进行垃圾回收.
3.自己也可以进行管理,也就是强制调用垃圾回收器GC,这在XNA中可能常见,毕竟它需要的内存是非常区大的.
4.在C/C++中,调用FREE/DELETE时,当然会立即释放内存,这就是所谓的动态内存分配
2008-08-08 14:20
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
上而的第2条打错了一个字,"并不一定要等到程序退出"
2008-08-08 14:21
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
回复 3# xlh5225 的帖子
恩,谢谢
XNA是基于DirectX的3D游戏开发环境
2008-08-08 19:24
YCVSCY
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2008-7-11
得分:0 
强调一下,根据谭老先生所说的"delete" 是"语句"而不是"函数";
"free"是函数,所以,delete的开销要比free的要小.
2008-08-10 18:51
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
回复 6# YCVSCY 的帖子
EN  delete 是个关键字 确实是语句
2008-08-11 11:34
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
得分:0 
[bo][un]YCVSCY[/un] 在 2008-8-10 18:51 的发言:[/bo]

强调一下,根据谭老先生所说的"delete" 是"语句"而不是"函数";
"free"是函数,所以,delete的开销要比free的要小.

让你看看new和delete的真实语义,在想想你说的话~:
内建数据类型版本:
  int* p=new int (5);
 扩展后:
  if(int *p=_new(sizeof(int)))
  {
      *p=5;
  }
delete p;
扩展后:
  if(p) _delete(p);
ADT版本:
  T* p = new T;
扩展后:
  if(T* p=_new(sizeof(T)))
  {
     try { p->T::T(); }
     catch(...)
     {
         _delete(p);
      }
   }
  delete p;
扩展后:
   if(p)
   {
       p->T::~T();
       _delete(p);
   }

樱花大战,  有爱.
2008-08-11 19:33
YCVSCY
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2008-7-11
得分:0 
[bo][un]中学者[/un] 在 2008-8-11 19:33 的发言:[/bo]


让你看看new和delete的真实语义,在想想你说的话~:
内建数据类型版本:
  int* p=new int (5);
 扩展后:
  if(int *p=_new(sizeof(int)))
  {
      *p=5;
  }
delete p;
扩展后:
  if(p) _delete(p);
AD ...



恕小弟愚昧,您的代码我没看懂,能麻烦您些详细一些可以吗?我在这里先谢谢了!!

但是我仔细看了看,有新的发现:
# include <iostream>
using namespace std;
int main()
{
    int *p = new int(5);
    cout <<*p<<endl<<p<<endl<<&p<<endl<<endl;
    delete p;
    cout <<*p<<endl<<p<<endl<<&p<<endl;
    return 0;
}

结果是:
   5
00031F18
0013FF7C

-572662307
00031F18
0013FF7C

发现delete只是删除了*p,而p还存在.

然后我进行调试,发现了 :
operator new:
004208E0   push        ebp
004208E1   mov         ebp,esp
004208E3   push        ecx
004208E4   push        1
004208E6   mov         eax,dword ptr [cb]
004208E9   push        eax
004208EA   call        _nh_malloc (00421ec0)
004208EF   add         esp,8

注意看红色的部分,call    _nh_malloc难道new 的实际是包含了
"call    _nh_malloc" 这一步.
那如此看来就是谭的书有问题了...

我很不明白,还请您指点迷津~~~~~~~~~
2008-08-13 13:51
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
得分:0 
new和delete本身是个函数,原型:
void* operator new(size_t );
void operator delete(void*);
所以它们是可以重载的...
但是这样,T* p=new T; delete p; 是语句..会被扩展成上面那样,这是编译器做的事情.删除后的堆内存会被完全地附上随机值,而堆栈上的释放却会保留当前值..所以你的指针指向并没有改变,只是那块内存不可用罢了.

樱花大战,  有爱.
2008-08-13 18:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-227272-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.301488 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved