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++提供了三种主要的内存分配方式: 1. **静态存储区域分配**: - 这种方式下的...
源码中会包含如何用C++实现二维数组来表示雷区,以及如何进行逻辑判断,显示安全和雷格子。 通过学习这些源代码,你不仅可以掌握C++编程基础,还能深入理解游戏开发中的关键概念,如游戏循环、图形渲染、用户输入...
**C++扫雷程序源代码详解** 扫雷游戏是一款经典的逻辑推理游戏,它在Windows操作系统中广为人知。本篇文章将深入探讨一个使用C++语言实现的扫雷程序,包括其设计思路、主要功能模块以及代码结构。通过阅读源代码和...
**C++可视化扫雷小游戏详解** C++可视化扫雷小游戏是一款经典的桌面游戏,它通过编程语言C++实现,为玩家提供了交互式的体验。这款游戏利用了C++的强大功能,结合了面向对象编程的思想,实现了游戏逻辑、图形用户...
本篇将深入探讨如何使用C++编写一款经典的扫雷游戏,这对于初学者来说是一个极好的实践项目,能够帮助理解面向对象编程、动态内存管理和事件驱动编程等概念。 ### 1. 面向对象编程 扫雷游戏的核心在于设计清晰的类...
C++中,可以使用结构体或类来表示每个格子的状态,并使用算法来生成随机的雷区布局。 9. **李白打酒加强版**(未提供具体内容,但可以推断): - 可能是一个基于数学或逻辑的趣味问题,可能需要理解故事背景并解决...
《C++扫雷代码实现详解》 扫雷,这款经典的Windows小游戏,以其简单却富有挑战性的玩法深受用户喜爱。本文将详细介绍如何使用C++语言实现扫雷游戏的编程过程,包括游戏规则、资源编辑、变量函数定义以及具体实现。 ...
《C++实现MFC扫雷游戏详解》 扫雷,这款经典的Windows系统小游戏,以其简单易上手、挑战性高的特点深受用户喜爱。本项目"Mine_sweeper.rar_Mine!_c++扫雷mfc"是用C++语言基于Microsoft Foundation Classes (MFC)...
【扫雷小游戏 C++ 实现详解】 扫雷是一款经典的单人益智游戏,深受玩家喜爱。用 C++ 来实现这款游戏,可以让我们深入了解面向对象编程、事件驱动编程以及游戏逻辑设计等多个方面的重要知识点。 1. **面向对象编程*...
《C++扫雷游戏开发详解》 扫雷游戏,这个小巧而经典的益智游戏,以其简单易懂的规则和挑战性的玩法,深受广大玩家喜爱。本文将深入探讨如何使用C++编程语言来实现这一游戏,旨在帮助正在学习C++的朋友们理解和实践...
【扫雷小游戏C++实现详解】 扫雷游戏是一款经典的单人益智游戏,玩家需要根据数字提示找出所有未被标记的雷区。本篇将详细解释C++版本的扫雷小游戏代码实现,主要涉及以下几个核心知识点: 1. **内存动态分配**: ...
在实际开发过程中,还会遇到如内存管理、错误处理等问题,这些都是提升编程技能的重要环节。尽管VC6.0已经较为老旧,但它作为经典工具,对于学习C++和MFC仍具有一定的参考价值。而扫雷游戏的实现,无疑是一个很好的...
### C++实现扫雷游戏详解 #### 一、游戏简介及规则 扫雷是一款非常经典的逻辑推理游戏,最初作为Windows操作系统自带的小游戏被广大用户所熟知。本篇将详细介绍如何使用C++语言结合Visual C++ (VC) 开发环境来实现...
5. **游戏逻辑**:扫雷游戏的逻辑包括雷区的生成、点击格子的判定、标记等,这些都需要在网络环境中进行处理,并且需要考虑并发执行时的线程安全。 6. **用户界面**(UI):客户端的界面设计,包括按钮、计时器、...
《扫雷游戏——Visual C++实现详解》 扫雷,这款经典的Windows系统自带小游戏,以其简单易上手、挑战智力的特点深受用户喜爱。在本文中,我们将深入探讨如何使用C++编程语言,结合Visual Studio IDE,来实现一个...
《基于MFC技术实现的扫雷游戏开发详解》 扫雷,这是一款经典的电脑小游戏,以其独特的逻辑性和挑战性深受用户喜爱。本文将探讨如何利用Microsoft Foundation Classes (MFC)库来开发一款与Windows自带扫雷游戏类似的...
《C++实现的控制台扫雷游戏——Buscaminas-cpp详解》 在编程世界里,经典的游戏总是能激发程序员们的创新精神。"Buscaminas-cpp"就是一个使用C++语言在控制台环境中实现的扫雷游戏,它不仅展示了C++的基本语法和...
2. **C++编程**:作为基础语言,C++为游戏的逻辑运算和内存管理提供了高效和灵活的控制。开发者使用C++编写游戏的核心算法,如雷区生成、数字计算、标记等。 3. **自定义UI**:不依赖于UI控件拖拽,意味着开发者...
在本项目中,我们将探讨使用Qt框架实现扫雷游戏的源码解析。 首先,Qt是一个跨平台的C++图形用户界面应用程序开发框架,广泛用于开发桌面应用、移动应用以及嵌入式系统。其丰富的API库和强大的设计工具使得开发者...