且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

更新时间:2022-10-02 22:35:38

本节书摘来自华章计算机《计算机系统:核心概念及软硬件实现(原书第4版)》一书中的第2章,第2.5节,作者:[美] J. 斯坦利·沃法德(J. Stanley Warford)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.5动态内存分配

在C++中,值存储在主存储器的3个不同区域:
全局变量存储在内存的固定位置。
局部变量存储在运行时栈。
动态分配的变量存储在堆中。
过程调用和返回时,不能控制堆的分配和释放,而是借助于指针变量来分配堆。堆的分配不是通过过程调用在运行时栈上自动触发,它称为动态内存分配。
2.5.1指针
当声明一个全局或者局部变量时,指定它的类型。例如,可以把类型指定为整数或字符或数组。类似地,当声明一个指针时,必须声明它所指向的类型。指针本身可以是全局变量,也可以是局部变量,但是它指向的值位于堆中,既不是全局变量也不是局部变量。
C++提供了两个运算符来控制动态内存分配:
new,在堆中分配一块空间。
delete,释放堆中的一块空间。
虽然用delete运算符释放内存非常重要,但本书并不阐述它是怎样进行的。本书中使用指针的程序都是软件设计的坏例子,因为省略了释放的过程。这些程序的目的是展示HOL6层和Asmb5层之间的关系,到第6章这个关系就会变得更明显,因为第6章会讲述程序的翻译。
new运算符要求它的右边是类型,该运算执行时做两件事情:
在堆中分配一个足够大的存储单元用于存放它右边类型的值。
返回一个指针,指向新分配的存储空间。
与指针有关的赋值有两种:给指针赋一个值,或者给指针指向的单元赋一个值。第一种赋值叫指针赋值,它按照下列规则执行:
如果p和q是指针,赋值p=q使得p指向q指向的同一单元。

《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配


图2-37是一个无实际意义的程序,只是为了说明new运算符的行为以及指针赋值的规则。它使用全局指针,如果是局部指针,输出也是一样的。如果是局部指针,那么它们会分配在运行时栈上而不是内存的固定位置中。
在全局指针的声明中
《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

变量名前的星号表示这个变量是一个指向整数的指针,而不是整数。图2-38a将一个指针的值图形化地表示为了一个小黑点。
图2-38b说明了new运算符的行为。它在堆上分配了一个足够大的单元来存储整数值,并把这个值返回给指针。这个赋值使得a指向新分配的单元。图2-38c展示了怎样访问指针指向的单元。因为a是指针,所以*a是a指针指向的单元。图2-38f说明了指针赋值规则。赋值c=a使c指向a指向的同一单元;类似地,赋值a=b使a 指向b指向的那个单元。在图2-38h中,该赋值不是对指针a进行赋值,而是对指针a指向的单元进行赋值。
《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

2.5.2结构
结构是C++中数据抽象的关键。它们允许程序员把基本类型的变量整合到一个单一的抽象数据类型中。数组和结构都是一组值,不过数组的所有单元要求类型必须是一样的,通过整型数值作为索引访问每个单元;而在结构中,各个单元可以是不同类型的。C++提供struct结构把多个值集合成一个组。C++程序员给每个称为字段的单元一个字段名。
图2-39所示的程序声明了一个名为person的struct,它有4个字段,分别叫作first、last、age和gender。该程序声明了一个叫bill的全局变量,其类型为person,字段first、last和gender是char类型,字段age是int类型。

《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

为了访问结构的字段,在变量和要访问的字段之间放一个句号,例如,if语句的测试条件
《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

将访问变量bill的名为gender的字段。
2.5.3链式数据结构
程序员经常把指针和结构结合起来实现链式数据结构。struct通常称为结点,指针指向结点,结点中又有指针字段。在数据结构中,结点的指针字段作为指向另一个结点的链接。图2-40是一个实现链表(linked list)数据结构的程序,第一个循环输入一个整数序列,以特殊的标记符号值-9999结束,输入流中的第一个值放在链表的末端;第二个循环输出链表中的每个元素。图2-41是图2-40所示程序最开始几条语句执行的历史记录。
指针值为0是一个特殊的值,它保证指针不指向任何单元。在C++程序中,它通常用作一个链式结构的标记符号值。语句
《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

把这个特殊的值赋给局部指针first。图2-41b把这个值图形化地表示为一个虚线三角。

《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配


用星号来访问指针指向的单元,用句号来访问结构的字段。如果一个指针指向一个struct,那么要访问struct,必须同时使用星号和句号。
例2.7下列语句将变量value的值赋给变量first指向的结构的data字段

![image](https://yqfile.alicdn.com/8d04a3f87252b88c8e0369006dbf820c0aadfd7c.png)        □

因为这种星号和句号的组合太常用了,所以C++提供了箭头运算符->,其格式是一个连接符紧接一个大于符号。例2.7中的语句可以用这个运算符缩写为
《计算机系统:核心概念及软硬件实现(原书第4版)》——2.5动态内存分配

如图2-41f、k所示。该程序用同样的缩写访问next字段,如图2-41g、l所示。