高质量C++/C编程指南-第7章-内存打点(4)
当前位置:以往代写 > C/C++ 教程 >高质量C++/C编程指南-第7章-内存打点(4)
2019-06-13

高质量C++/C编程指南-第7章-内存打点(4)

高质量C++/C编程指南-第7章-内存打点(4)

7.5 free和delete把指针怎么啦?
7.7 杜绝“野指针”
“野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判定。可是“野指针”是很危险的,if语句对它不起浸染。

“野指针”的成因主要有两种:

(1)指针变量没有被初始化。任何指针变量刚被建设时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在建设的同时该当被初始化,要么将指针配置为NULL,要么让它指向正当的内存。譬喻

char *p = NULL;

char *str = (char *) malloc(100);

(2)指针p被free可能delete之后,没有置为NULL,让人误觉得p是个正当的指针。拜见7.5节。

(3)指针操纵逾越了变量的浸染范畴。这种环境让人防不胜防,示例措施如下:

class A

{

public:

void Func(void){ cout << “Func of class A” << endl; }

};

void Test(void)

{

A *p;

{

A a;

p = &a; // 留意 a 的生命期

}

p->Func(); // p是“野指针”

}

函数Test在执行语句p->Func()时,工具a已经消失,而p是指向a的,所以p就成了“野指针”。但奇怪的是我运行这个措施时居然没有堕落,这大概与编译器有关。

7.8 有了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如何实现工具的动态内存打点,见示例7-8。

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; // 排除而且释放内存

}

示例7-8 用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也一样。

    关键字:

在线提交作业