C语言内存分配详解5


};

void UseMallocFree(void)

{

 Obj *a = (obj *)malloc(sizeof(obj)); // 申请动态内存

 a->Initialize(); // 初始化

 //…

 a->Destroy(); // 清除工作

 free(a); // 释放内存

}

void UseNewDelete(void)

{

 Obj *a = new Obj; // 申请动态内存并且初始化

 //…

 delete a; // 清除并且释放内存

}

     示例6 用malloc/free和new/delete如何实现对象的动态内存管理

  类Obj的函数Initialize模拟了构造函数的功能,函数Destroy模拟了析构函数的功能。

函数UseMallocFree中,由于malloc/free不能执行构造函数与析构函数,必须调用成员函数

Initialize和Destroy来完成初始化与清除工作。函数UseNewDelete则简单得多。

  所以我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。由于

内部数据类型的"对象"没有构造与析构的过程,对它们而言malloc/free和new/delete是等

价的。

  既然new/delete的功能完全覆盖了malloc/free,为什么C 不把malloc/free淘汰出局呢?

这是因为C 程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。

  如果用free释放"new创建的动态对象",那么该对象因无法执行析构函数而可能导致程

序出错。如果用delete释放"malloc申请的动态内存",理论上讲程序不会出错,但是该程序

的可读性很差。所以new/delete必须配对使用,malloc/free也一样。

  7、内存耗尽怎么办?

  如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存

申请失败。通常有三种方式处理"内存耗尽"

  (1)判断指针是否为NULL,如果是则马上用return语句终止本函数。例如:

void Func(void)

{

 A *a = new A;

 if(a == NULL)

 {

  return;

 }

 …

}

  (2)判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行。例如:

void Func(void)

{

 A *a = new A;

 if(a == NULL)

 {

  exit(1);

 }

 …

}

  (3)为new和malloc设置处理函数。例如Visual C 可以用_set_new_hander函数为

new设置用户自己定义的处理函数,也可以让malloc享用与new相同的处理函数。详

细内容请参考C 使用手册。

  上述(1)(2)方式使用最普遍。如果一个函数内有多处需要申请动态内存,那么方式(1)

就显得力不从心(释放内存很麻烦),应该用方式(2)来处理。

  很多人不忍心用exit(1),问:"不编写出错处理程序,让自己解决行不行?"

  不行。如果发生"内存耗尽"这样的事情,一般说来应用程序已经无药可救。如果不用

exit(1) 把坏程序杀死,它可能会害死。道理如同:如果不把歹徒击毙,歹徒在老死之

前会犯下更多的罪。

  有一个很重要的现象要告诉大家。对于32位以上的应用程序而言,无论怎样使用malloc

与new,几乎不可能导致"内存耗尽"。我在 98下用Visual C 编写了测试程序,见示

例7。这个程序会无休止地运行下去,根本不会终止。因为32位支持"虚存",内存

用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,Window 98已经累得对键盘、鼠标

毫无反应。

  我可以得出这么一个结论:对于32位以上的应用程序,"内存耗尽"错误处理程序毫无用

处。这下可把Unix和程序员们乐坏了:反正错误处理程序不起作用,我就不写了,省

了很多麻烦。

  我不想误导读者,必须强调:不加错误处理将导致程序的质量很差,千万不可因小失大。

void main(void)

{

 float *p = NULL;

 while(TRUE)

 {

  p = new float[1000000];

  if(p==NULL)

   exit(1);

 }

}

  示例7试图耗尽的内存

声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 智乐兔
转载请注明:转自《C语言内存分配详解5
本文地址:https://www.zhiletu.com/archives-649.html
关注公众号:智乐兔

赞赏

wechat pay微信赞赏alipay pay支付宝赞赏

上一篇
下一篇

相关文章

在线留言

你必须 登录后 才能留言!

在线客服
在线客服 X

售前: 点击这里给我发消息
售后: 点击这里给我发消息

智乐兔官微