注册 登录
编程论坛 C++教室

内存释放问题

vfdff 发布于 2008-08-08 09:54, 2023 次点击
在 C# 语言里,只有为某个对象申请内存空间的new ,而没有对应的delete,因为C#把释放内存的工作交给了系统,而系统一般只是在这个程序运行 结束时才一次性的把分配给他的堆内存全部回收,而程序本省不能直接释放某个对象的 堆内存。但是C/C++里有free/delete,这是否意味着某次调用这些函数的时候系统就将执行堆内存的回收?
13 回复
#2
xzx10020022008-08-08 12:56
期待标准答案。。。。。
#3
xlh52252008-08-08 14:20
1.首先就C#而言,确实对于大多数程序来说,并不需要程序员自己来管理堆内存,因为C#有很好的"垃圾回收"机制,但是这种垃圾回收机制的代价是非常大的,这一点需要明确.
2.其次,并且一定要等到程序退出,才进行垃圾回收,当你的程序空间不足时,系统为自动进行垃圾回收.
3.自己也可以进行管理,也就是强制调用垃圾回收器GC,这在XNA中可能常见,毕竟它需要的内存是非常区大的.
4.在C/C++中,调用FREE/DELETE时,当然会立即释放内存,这就是所谓的动态内存分配
#4
xlh52252008-08-08 14:21
上而的第2条打错了一个字,"并不一定要等到程序退出"
#5
vfdff2008-08-08 19:24
回复 3# xlh5225 的帖子
恩,谢谢
XNA是基于DirectX的3D游戏开发环境
#6
YCVSCY2008-08-10 18:51
强调一下,根据谭老先生所说的"delete" 是"语句"而不是"函数";
"free"是函数,所以,delete的开销要比free的要小.
#7
vfdff2008-08-11 11:34
回复 6# YCVSCY 的帖子
EN  delete 是个关键字 确实是语句
#8
中学者2008-08-11 19:33
[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);
   }
#9
YCVSCY2008-08-13 13:51
[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" 这一步.
那如此看来就是谭的书有问题了...

我很不明白,还请您指点迷津~~~~~~~~~
#10
中学者2008-08-13 18:28
new和delete本身是个函数,原型:
void* operator new(size_t );
void operator delete(void*);
所以它们是可以重载的...
但是这样,T* p=new T; delete p; 是语句..会被扩展成上面那样,这是编译器做的事情.删除后的堆内存会被完全地附上随机值,而堆栈上的释放却会保留当前值..所以你的指针指向并没有改变,只是那块内存不可用罢了.
#11
YCVSCY2008-08-14 08:08
哦,原来是这样啊!
我在仔细看看书.
#12
vfdff2008-08-14 09:26
回复 10# 中学者 的帖子
这么说 关键字可以重载成函数了 ?
#13
中学者2008-08-15 20:57
回复 12# vfdff 的帖子
不是,意义不一样......
单独的new/delete是函数.但是组合用就是语句,也就看成关键字吧~
#14
vfdff2008-08-16 23:48
回复 10# 中学者 的帖子
delete p;后,不是执行了 p = NULL;吗?
1