`
weiyinchao88
  • 浏览: 1234361 次
文章分类
社区版块
存档分类
最新评论

踏入C++中的雷区——C++内存管理详解(III)

 
阅读更多
6、有了malloc/free为什么还要new/delete?

  malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

  对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

   因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。我们先看一看malloc/free和new/delete如何实现对象的动态内存管理,见示例6。

class Obj
{
 public :
  Obj(void){ cout << “Initialization” << endl; }
  ~Obj(void){ cout << “Destroy” << endl; }
  void Initialize(void){ cout << “Initialization” << endl; }
  void Destroy(void){ cout << “Destroy” << endl; }
};
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)
 {
  cout << “Memory Exhausted” << endl;
  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,几乎不可能导致“内存耗尽”。我在Windows 98下用Visual C++编写了测试程序,见示例7。这个程序会无休止地运行下去,根本不会终止。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,Window 98已经累得对键盘、鼠标毫无反应。

  我可以得出这么一个结论:对于32位以上的应用程序,“内存耗尽”错误处理程序毫无用处。这下可把Unix和Windows程序员们乐坏了:反正错误处理程序不起作用,我就不写了,省了很多麻烦。

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

void main(void)
{
 float *p = NULL;
 while(TRUE)
 {
  p = new float[1000000];
  cout << “eat memory” << endl;
  if(p==NULL)
   exit(1);
 }
}


  示例7试图耗尽操作系统的内存

分享到:
评论

相关推荐

    C++中的雷区——C++内存管理详解

    C++中的雷区——C++内存管理详解C++中的雷区——C++内存管理详解C++中的雷区——C++内存管理详解C++中的雷区——C++内存管理详解

    踏入C++中的雷区C++内存管理详解

    ### C++内存管理详解 #### 一、内存分配方式 C++中的内存管理非常重要,它直接关系到程序的稳定性和性能。根据不同的应用场景,C++提供了三种主要的内存分配方式: 1. **静态存储区域分配**: - 这种方式下的...

    《Visual C++ 游戏开发经典案例详解》源代码

    源码中会包含如何用C++实现二维数组来表示雷区,以及如何进行逻辑判断,显示安全和雷格子。 通过学习这些源代码,你不仅可以掌握C++编程基础,还能深入理解游戏开发中的关键概念,如游戏循环、图形渲染、用户输入...

    C++扫雷程序源代码

    **C++扫雷程序源代码详解** 扫雷游戏是一款经典的逻辑推理游戏,它在Windows操作系统中广为人知。本篇文章将深入探讨一个使用C++语言实现的扫雷程序,包括其设计思路、主要功能模块以及代码结构。通过阅读源代码和...

    C++可视化扫雷小游戏

    **C++可视化扫雷小游戏详解** C++可视化扫雷小游戏是一款经典的桌面游戏,它通过编程语言C++实现,为玩家提供了交互式的体验。这款游戏利用了C++的强大功能,结合了面向对象编程的思想,实现了游戏逻辑、图形用户...

    C++程序小例子

    本篇将深入探讨如何使用C++编写一款经典的扫雷游戏,这对于初学者来说是一个极好的实践项目,能够帮助理解面向对象编程、动态内存管理和事件驱动编程等概念。 ### 1. 面向对象编程 扫雷游戏的核心在于设计清晰的类...

    2022年第十三届蓝桥杯省赛 C/C++ B组 真题

    C++中,可以使用结构体或类来表示每个格子的状态,并使用算法来生成随机的雷区布局。 9. **李白打酒加强版**(未提供具体内容,但可以推断): - 可能是一个基于数学或逻辑的趣味问题,可能需要理解故事背景并解决...

    C++扫雷代码

    《C++扫雷代码实现详解》 扫雷,这款经典的Windows小游戏,以其简单却富有挑战性的玩法深受用户喜爱。本文将详细介绍如何使用C++语言实现扫雷游戏的编程过程,包括游戏规则、资源编辑、变量函数定义以及具体实现。 ...

    Mine_sweeper.rar_Mine!_c++扫雷mfc

    《C++实现MFC扫雷游戏详解》 扫雷,这款经典的Windows系统小游戏,以其简单易上手、挑战性高的特点深受用户喜爱。本项目"Mine_sweeper.rar_Mine!_c++扫雷mfc"是用C++语言基于Microsoft Foundation Classes (MFC)...

    扫雷 c++ 小游戏

    【扫雷小游戏 C++ 实现详解】 扫雷是一款经典的单人益智游戏,深受玩家喜爱。用 C++ 来实现这款游戏,可以让我们深入了解面向对象编程、事件驱动编程以及游戏逻辑设计等多个方面的重要知识点。 1. **面向对象编程*...

    C++扫雷游戏

    《C++扫雷游戏开发详解》 扫雷游戏,这个小巧而经典的益智游戏,以其简单易懂的规则和挑战性的玩法,深受广大玩家喜爱。本文将深入探讨如何使用C++编程语言来实现这一游戏,旨在帮助正在学习C++的朋友们理解和实践...

    扫雷小游戏代码c++版.pdf

    【扫雷小游戏C++实现详解】 扫雷游戏是一款经典的单人益智游戏,玩家需要根据数字提示找出所有未被标记的雷区。本篇将详细解释C++版本的扫雷小游戏代码实现,主要涉及以下几个核心知识点: 1. **内存动态分配**: ...

    用vc6.0写的扫雷游戏

    在实际开发过程中,还会遇到如内存管理、错误处理等问题,这些都是提升编程技能的重要环节。尽管VC6.0已经较为老旧,但它作为经典工具,对于学习C++和MFC仍具有一定的参考价值。而扫雷游戏的实现,无疑是一个很好的...

    C++ 扫雷游戏

    ### C++实现扫雷游戏详解 #### 一、游戏简介及规则 扫雷是一款非常经典的逻辑推理游戏,最初作为Windows操作系统自带的小游戏被广大用户所熟知。本篇将详细介绍如何使用C++语言结合Visual C++ (VC) 开发环境来实现...

    基于Visual C++实现的网络扫雷游戏

    5. **游戏逻辑**:扫雷游戏的逻辑包括雷区的生成、点击格子的判定、标记等,这些都需要在网络环境中进行处理,并且需要考虑并发执行时的线程安全。 6. **用户界面**(UI):客户端的界面设计,包括按钮、计时器、...

    saolei.rar_visual c

    《扫雷游戏——Visual C++实现详解》 扫雷,这款经典的Windows系统自带小游戏,以其简单易上手、挑战智力的特点深受用户喜爱。在本文中,我们将深入探讨如何使用C++编程语言,结合Visual Studio IDE,来实现一个...

    用MFC开发的扫雷游戏程序(含源码)

    《基于MFC技术实现的扫雷游戏开发详解》 扫雷,这是一款经典的电脑小游戏,以其独特的逻辑性和挑战性深受用户喜爱。本文将探讨如何利用Microsoft Foundation Classes (MFC)库来开发一款与Windows自带扫雷游戏类似的...

    Buscaminas-cpp:Consola中的Buscaminas utilizando C ++

    《C++实现的控制台扫雷游戏——Buscaminas-cpp详解》 在编程世界里,经典的游戏总是能激发程序员们的创新精神。"Buscaminas-cpp"就是一个使用C++语言在控制台环境中实现的扫雷游戏,它不仅展示了C++的基本语法和...

    基于QT扫雷小游戏.rar

    2. **C++编程**:作为基础语言,C++为游戏的逻辑运算和内存管理提供了高效和灵活的控制。开发者使用C++编写游戏的核心算法,如雷区生成、数字计算、标记等。 3. **自定义UI**:不依赖于UI控件拖拽,意味着开发者...

    扫雷小游戏详解源码1111111

    在本项目中,我们将探讨使用Qt框架实现扫雷游戏的源码解析。 首先,Qt是一个跨平台的C++图形用户界面应用程序开发框架,广泛用于开发桌面应用、移动应用以及嵌入式系统。其丰富的API库和强大的设计工具使得开发者...

Global site tag (gtag.js) - Google Analytics