第二十章指针二为指针分配和释放空间 20.1理解指针的两种“改变” 20.1.1改变指针的值 改变指针所指的变量的值 20.1.3两种改变?一种改变? 20.2C++方式的内存分配与释放new和 delete 20.2.1new 20.2.2在new时初始化内存的值 20.2.3 delete 20.2.4实验:new和 delete 20.2.5new和 delete的关系 0.3new[]和 delete[] 20.3.1new[]/ delete[]基本用法 20.3.2new[]/ delete[]示例 20.3.3详解指向连续空间的指针 20.4 delete/ delete[]的两个注意点 20.4.1一个指针被删除时,应指向最初的地址 20.4.2已释放的空间,不可重复释放 20.5C方式的内存管理 20.5.1分配内存 malloc函数 20.5.2释放内存free函数 20.5.3重调空间的大小: realloc函数 20.5.4 malloc、 realloc、free的例子 20.1理解指针的两种“改变
第二十章 指针 二 为指针分配和释放空间 20.1 理解指针的两种“改变” 20.1.1 改变指针的值 20.1.2 改变指针所指的变量的值 20.1.3 两种改变?一种改变? 20.2 C++ 方式的内存分配与释放 new 和 delete 20.2.1 new 20.2.2 在 new 时初始化内存的值 20.2.3 delete 20.2.4 实验: new 和 delete 20.2.5 new 和 delete 的关系 20.3 new [] 和 delete [] 20.3.1 new[] / delete[] 基本用法 20.3.2 new []/ delete[] 示例 20.3.3 详解指向连续空间的指针 20.4 delete/delete[] 的两个注意点 20.4.1 一个指针被删除时,应指向最初的地址 20.4.2 已释放的空间,不可重复释放 20.5 C 方式的内存管理 20.5.1 分配内存 malloc 函数 20.5.2 释放内存 free 函数 20.5.3 重调空间的大小: realloc 函数 20.5.4 malloc、realloc、free 的例子 20.1 理解指针的两种“改变
普通变量(非指针,简单类型变量)只能改变值 1) int a= 10 第1行代码,声明int类型变量a,并且初始化a的值为100 到第3行代码,变量a的值被改变成200 对于非指针的简单变量,能被程序改变的,只有这一种。而指针变量,似乎有两种改变 20.1.1改变指针的值 这一点和普通变量一致。但要特别注意,“改变指针的值”引起的结果是什么?其实就是“ 变指针的指向”。 因为,指针的值是某个变量的地址。假如指针P原来的值是A变量的地址,现在改为B变量 的地址。我们称为:“P由指向A改为指向B”。这就是指针的第一种改变。 以下是示例代码 int A, B 1) 3)P=&B 1)行代码中,P的值为&A,即P指向变量A。 到3)行代码中,P的值变为&B,即改为指向变量B 下面讲:指针的第二种改变。通过指针,改变指针所指的变量的值
普通变量(非指针,简单类型变量)只能改变值: 1) int a = 100; 2) ... 3) a = 200; 第 1 行代码,声明 int 类型变量 a,并且初始化 a 的值为 100。 到第 3 行代码,变量 a 的值被改变成 200。 对于非指针的简单变量,能被程序改变的,只有这一种。而指针变量,似乎有两种改变。 20.1.1 改变指针的值 这一点和普通变量一致。但要特别注意,“改变指针的值”引起的结果是什么?其实就是“改 变指针的指向”。 因为,指针的值是某个变量的地址。假如指针 P 原来的值是 A 变量的地址,现在改为 B 变量 的地址。我们称为:“P 由指向 A 改为指向 B”。这就是指针的第一种改变。 以下是示例代码: int* P; int A,B; 1) P = &A; 2) ... 3) P = &B; 1) 行代码中,P 的值为 &A,即 P 指向变量 A。 到 3)行代码中,P 的值变为&B,即改为指向变量 B。 下面讲:指针的第二种改变。通过指针,改变指针所指的变量的值
20.12改变指针所指的变量的值 复习前一章,我们知道通过*(地址解析符),可以得到、或改变指针所指的变量的值 nta=100 P=&A *P=200 out <<a endl 代码中加粗的那一行:*P=200;,其作用完全等同于:A=200 所以,最后一行输出的结果是200。 这就是指针的第二种改变:所指变量的值,被改变了。 20.13两种改变?一种改变? 两种改变的意义不同 改变一:改变指针本身的值(改变指向)。 改变二:改变指针指向的变量的值。 从代码上看 第一种改变,P=&A;左值(等号左边的值)是变量本身,右值则是一个地址
20.1.2 改变指针所指的变量的值 复习前一章,我们知道通过 * (地址解析符),可以得到、或改变指针所指的变量的值。 int* P; int A = 100; P = &A; * P = 2 0 0; cout << A << endl; 代码中加粗的那一行:*P = 200; ,其作用完全等同于:A = 200; 所以,最后一行输出的结果是 200。 这就是指针的第二种改变:所指变量的值,被改变了。 20.1.3 两种改变?一种改变? 两种改变的意义不同: 改变一:改变指针本身的值(改变指向)。 改变二:改变指针指向的变量的值。 从代码上看: 第一种改变,P = &A; 左值(等号左边的值)是变量本身,右值则是一个地址
而第二种改变,*P=200;左值通过星号对P操作,来取得P指向的变量:右值是普通的值。 理解,区分对指针的两种改变,才能学会如何使用指针 请思考:上一章讲的“指针的加减操作”,是对指针的哪一种改变? 最后需要说明,严格意义上,指针仍然只有一种改变,即改变指针本身的值。改变指针指向 的变量,应视为对另一变量的改变,只不过在代码上,它通过指针来进行,而不是直接对另 变量进行操作 为指针分配、释放内存空间 之前,我们给指针下的定义是“指针是一个变量,它存放的值是另一个变量的地址”。 比如: It a nt*p=&a 看,a就是“另一个变量”,p指向了a 我们知道,变量总是要占用一定的内存空间,比如上面的a,就占用了4个字节 ( sizeof(int))。这四个字节属于谁?当然属于变量a,而不是p 现在要讲的是:也可以单独为指针分配一段新的内存空间。这一段内容不属于某个变量。 20.2C++方式的内存分配与释放neW和 delete 在内存管理上,C++和C有着完全不同的两套方案。当然,C++的总是同时兼容C。C的那 一套方案在C++里同样可行。 我们首先看看纯C++的那 new和 delete e
而第二种改变,*P = 200; 左值通过星号对 P 操作,来取得 P 指向的变量;右值是普通的值。 理解,区分对指针的两种改变,才能学会如何使用指针。 请思考:上一章讲的“指针的加减操作”,是对指针的哪一种改变? 最后需要说明,严格意义上,指针仍然只有一种改变,即改变指针本身的值。改变指针指向 的变量,应视为对另一变量的改变,只不过在代码上,它通过指针来进行,而不是直接对另一 变量进行操作。 为指针分配、释放内存空间 之前,我们给指针下的定义是“指针是一个变量,它存放的值是另一个变量的地址”。 比如: int a; int* p = &a; 看,a 就是“另一个变量”,p 指向了 a。 我们知道,变量总是要占用一定的内存空间,比如上面的 a,就占用了 4 个字节 (sizeof(int))。这四个字节属于谁?当然属于变量 a,而不是 p。 现在要讲的是:也可以单独为指针分配一段新的内存空间。这一段内容不属于某个变量。 20.2 C++ 方式的内存分配与释放 new 和 delete 在内存管理上,C++ 和 C 有着完全不同的两套方案。当然,C++的总是同时兼容 C。C 的那 一套方案在 C++里同样可行。 我们首先看看纯 C++的那一套: new 和 delete
new,从字面上看意思为“新”:而 delete字面意思为“删除”。二者在C++中内存管理 中大致的功能,应是一个为“新建”,一个为“删除” 20.2.1neW new是c++的一个关键字。被当作像+、-、*、/一样的操作符。它的操作结果是在申请 到一段指定数据类型大小的内存 语法: 指针变量=new数据类型 将做三件事 1、主动计算指定数据类型需要的内存空间大小 2、返回正确的指针类型 3、在分配内存的一,将按照语法规则,初始化所分配的内存 这是什么意思呢?看看例子吧 1nt* p 和以往不一样,p这回不再“寄人篱下”,并不是指向某个已存在的变量,而是直接指向一 段由new分配而来的新内存空间 “p指向一段由new分配而来的新内存空间”这句话等同于 new分配一段新的内存空间,然后将该内存空间的地址存入到变量p中
new ,从字面上看意思为 “新”;而 delete 字面意思为“删除”。二者在 C++中内存管理 中大致的功能,应是一个为“新建”,一个为“删除”。 20.2.1 new new 是 c++ 的一个关键字。被当作像 +、-、* 、/ 一样的操作符。它的操作结果是在申请 到一段指定数据类型大小的内存。 语法: 指针变量 = new 数据类型; new 将做三件事: 1、主动计算指定数据类型需要的内存空间大小; 2、返回正确的指针类型; 3、在分配内存的一,将按照语法规则,初始化所分配的内存。 这是什么意思呢?看看例子吧: int* p; p = new int; 和以往不一样,p 这回不再“寄人篱下”,并不是指向某个已存在的变量,而是直接指向一 段由 new 分配而来的新内存空间。 “p 指向一段由 new 分配而来的新内存空间” 这句话等同于: “new 分配一段新的内存空间,然后将该内存空间的地址存入到变量 p 中
所以,最终p中仍然是存储了一个变量的地址,只是,这是一个“无名”变量 指向原有的某个变量,和指向一段新分配的内存空间,有什么区别呢? “原有的变量”,可以比喻成指向一间原有的,并且有主的房间。而“新分配的内存空间 则像是一个“临时建筑物”。我们必须在不用它的时候,主动将它拆迁。拆迁的工作由 delete 来完成。 当指针变量通过new,而得到一个内存地址后,我们就可以像以前的所说的,通过该指针 通过*号,而对该内存地址(一个无名的变量),进行操作 int* p new int cout *p < endl: 屏幕将输出100 20.2.2在neW时初始化内存的值 new也可以在申请内存空间时,直接设置该段内存里要放点什么 语法: 指针变量=new数据类型(初值 这样,上例可以改为 int*p= new int(100) cout < *p<< endl
所以,最终 p 中仍然是存储了一个变量的地址,只是,这是一个“无名”变量。 指向原有的某个变量,和指向一段新分配的内存空间,有什么区别呢? “原有的变量”,可以比喻成指向一间原有的,并且有主的房间。而“新分配的内存空间”, 则像是一个“临时建筑物”。我们必须在不用它的时候,主动将它拆迁。拆迁的工作由 delete 来完成。 当指针变量通过 new ,而得到一个内存地址后,我们就可以像以前的所说的,通过该指针, 通过*号,而对该内存地址(一个无名的变量),进行操作。 如: int* p = new int; *p = 100; cout << *p << endl; 屏幕将输出 100。 20.2.2 在 new 时初始化内存的值 new 也可以在申请内存空间时,直接设置该段内存里要放点什么. 语法: 指针变量 = new 数据类型(初值); 这样,上例可以改为: int* p = new int( 100); cout << *p << endl;
如果你申请的是字符类型的空间,并且想初始化为‘A char* pchar new char ('A') 20.2.3 delete 语法: delete指针变量 delete将释放指定指针所指向的内存空间 举例 int* p new Int *p=100; out < *p < endl delete p system("PAUSE") 注意,当一个指针接受 delete操作后,它就又成了一个“指向不明”的指针。尽管我们可 以猜测它还是指向“原来的房子”,然而,事实上,那座“房子”已经被 delete“拆迁”掉 了
如果你申请的是字符类型的空间,并且想初始化为‘A': char* pchar = new char('A'); 20.2.3 delete 语法: d e lete 指针变量; delete 将释放指定指针所指向的内存空间。 举例: int* p; p = new int; *p = 100; cout << *p << endl; delete p; system("PAUSE"); 注意,当一个指针接受 delete 操作后,它就又成了一个“指向不明”的指针。尽管我们可 以猜测它还是指向“原来的房子”,然而,事实上,那座“房子”已经被 delete “拆迁”掉 了
20.24实验:neW和 delete 很简单的例子 首先,在CB新建一个控制台程序。然后把上一小节的代码放到main(函数内。运行。结果 看按任意键继续 (new和 delete) 按任意键退出后,保存工程(Ctrl+ Shift+S)。 接下来我们来观察指针变量被 delete之后,所指向的内存会是什么。但,这是一件犯了C、 C++编程大忌的事:访问一个已经 delete的指针的值。如果你最近运气很差,你的CB可能会 被强行退出。所以,你明白我们为什么要先存盘了,对不? 在前面的代码中,加入以下加粗加红的一行(同时,你也应注意我的加的注释) cout<〈*p<<endl delete p //lp所指向的内存空间已经被释放 cout<<*<endl;//我们故意去访问此时p所指的内存
20.2.4 实验: new 和 delete 很简单的例子。 第一步: 首先,在 CB 新建一个控制台程序。然后把上一小节的代码放到 main()函数内。运行。结果 如下: (new 和 delete) 按任意键退出后,保存工程(Ctrl + Shift + S)。 第二步: 接下来我们来观察指针变量被 delete 之后,所指向的内存会是什么。但,这是一件犯了 C、 C++编程大忌的事:访问一个已经 delete 的指针的值。如果你最近运气很差,你的 CB 可能会 被强行退出。所以,你明白我们为什么要先存盘了,对不? 在前面的代码中,加入以下加粗加红的一行(同时,你也应注意我的加的注释): int* p; p = new int; *p = 100; cout << *p << endl; delete p; //p 所指向的内存空间已经被释放 c o ut < < * p < < e ndl; / /我们故意去访问此时 p 所指的内存
system("PAUSE") 运行结果: 4424844 青按任意键继续 (访问 delete之后的指针) 44244844??在你的机器可能不是这个数,但一定同样是怪怪的值。原来是好端端的100, 现在却成了44244844。不要问我这是为什么?昨天来时,美眉还住在这里一座别致小阁楼里, 今日故地重游,这里竟成废墟一片,依稀只见破墙上尚有:“拆!一一城建局”的字样?! new是管建房的,而 delete就一个字:拆! 请大家自行在CB上完成本实验。我没有提供本题的实际工程 20.2.5new和 delete的关系 如果只有“建房”而没有“拆房”,那么程序就会占用内存越来越多。所以,当使用new为 某个指针分配出内存空间后,一定要记得在不需要再使用时,用 delete删除。下面是一个例 子。演示new和 delete的对应使用。 //建屋和入住: 1)int* p new int(100) //使用: 2)cout < *p<< endl
system("PAUSE"); 运行结果: (访问 delete 之后的指针) 44244844??在你的机器可能不是这个数,但一定同样是怪怪的值。 原来是好端端的 100, 现在却成了 44244844。不要问我这是为什么?昨天来时,美眉还住在这里一座别致小阁楼里, 今日故地重游,这里竟成废墟一片,依稀只见破墙上尚有:“拆!——城建局”的字样?! new 是管建房的,而 delete 就一个字:拆! 请大家自行在 CB 上完成本实验。我没有提供本题的实际工程。 20.2.5 new 和 delete 的关系 如果只有“建房”而没有“拆房”,那么程序就会占用内存越来越多。所以,当使用 new 为 某个指针分配出内存空间后,一定要记得在不需要再使用时,用 delete 删除。下面是一个例 子。演示 new 和 delete 的对应使用。 //建屋和入住: 1) int* p = new int(100); //使用: 2) cout << *p << endl;
//拆: 3 delete 看,第1句,申请了4字节的内存空间,同时存入值为100的整数 第2句,在屏幕上输出入住者的值(100)。 第3句,释放内存(这4字节被系统收回准备做其它用途)。入住者呢?自然消失了。 前面举的例子都是在new一个int类型,其它类型也一样 char* a= new char(A) B cout < *a < end delete a boo lek b cout <<true"<< endl 但是这些都是简单数据类型,如果要分配数组一样的连续空间,则需要使另一对武器 neW[]和d []
//拆: 3) delete p; 看,第 1 句,申请了 4 字节的内存空间,同时存入值为 100 的整数。 第 2 句,在屏幕上输出入住者的值 (100)。 第 3 句,释放内存(这 4 字节被系统收回准备做其它用途)。入住者呢?自然消失了。 前面举的例子都是在 new 一个 int 类型,其它类型也一样: char* a = new char('A'); cout << *a << endl; *a = 'B'; cout << *a << end; delete a; bool* b = new bool; *b = true; if (*b) cout << "true" << endl; else cout << "fale" << endl; 但是这些都是简单数据类型,如果要分配数组一样的连续空间,则需要使另一对武器。 20.3 new [] 和 delete []