C语言入门基础 第16章 堆管理

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

北京源智天下科技有限公司
联系方式:http://www.rzchina.net
16.3
动态数组的实现
C语言的内建数组属于静态数组,程序运行前就必须确定其 语言的内建数组属于静态数组, 语言的内建数组属于静态数组 数组容量。但是, 数组容量。但是,有的数组需要的容量在程序运行后才 会知道;对于这些数组, 会知道;对于这些数组,如果使用静态数组只能为其预 先设定一个足够大的数组容量, 先设定一个足够大的数组容量,因此造成内存空间的浪 本节将讨论如何借助堆管理来实现动态数组。 费。本节将讨论如何借助堆管理来实现动态数组。
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
16.1
分配和释放
在前面接触的指针变量都是指向栈上分配的空间, 在前面接触的指针变量都是指向栈上分配的空间,这些空间 都是由系统自动管理的C标准函数库提供了许多函数来实 都是由系统自动管理的 标准函数库提供了许多函数来实 现对堆上内存的管理,其中包括: 函数、 现对堆上内存的管理,其中包括:malloc函数、free函 函数 函 函数和realloc函数。使用这些函数都需要包 函数。 数、calloc函数和 函数和 函数 含头文件stdlib.h。本节先讨论 函数和free函数的 含头文件 。本节先讨论malloc函数和 函数和 函数的 使用。 使用。
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
free函数 16.1.2 free函数
由于形参为void指针,free函数可以接受任意类型的指针实参。 指针, 函数可以接受任意类型的指针实参。 由于形参为 指针 函数可以接受任意类型的指针实参 例如: 例如: 01 char * p1 = NULL; 02 int * p2 = NULL; 03 … 04 free(p1); 05 free(p2); 但是, 函数只释放指针指向的内容, 但是,free函数只释放指针指向的内容,而该指针的值仍然指向 函数只释放指针指向的内容 原来指向的地方,此时指针为野指针, 原来指向的地方,此时指针为野指针,如果此时操作该指针会 导致不可预期的错误。安全的做法是:在使用free函数释放指 导致不可预期的错误。安全的做法是:在使用 函数释放指 针指向的空间之后,将指针值置为NULL。因此,对于范例 针指向的空间之后,将指针值置为 。因此,对于范例161,需要在 语句前加入以下两行语句: ,需要在return语句前加入以下两行语句: 语句前加入以下两行语句 01 free(p); 02 p = NULL;
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
realloc函数 16.2.2 realloc函数
realloc函数的功能比 函数的功能比malloc函数和 函数和calloc函数更为丰富, 函数更为丰富, 函数的功能比 函数和 函数更为丰富 可实现内存分配和内存释放的功能。其函数声明如下: 可实现内存分配和内存释放的功能。其函数声明如下: void *realloc(void *p, int n); 其中,指针p必须为指向堆内存空间的指针,即由 必须为指向堆内存空间的指针, 其中,指针 必须为指向堆内存空间的指针 即由malloc函 函 函数或realloc函数分配空间的指针。realloc 函数分配空间的指针。 数、calloc函数或 函数或 函数分配空间的指针 函数将指针p指向的内存块的大小改变为 字节。如果n小 指向的内存块的大小改变为n字节 函数将指针 指向的内存块的大小改变为 字节。如果 小 于或等于p之前指向的空间大小 之前指向的空间大小, 于或等于 之前指向的空间大小,那么保持原有状态不变 如果n大于原来 之前指向的空间大小, 大于原来p之前指向的空间大小 。如果 大于原来 之前指向的空间大小,那么系统将重 新为p从堆上分配一块大小为 的内存空间,同时将p原来 从堆上分配一块大小为n的内存空间 新为 从堆上分配一块大小为 的内存空间,同时将 原来 指向空间的内容依次复制到新的内存空间上, 之前指向 指向空间的内容依次复制到新的内存空间上,p之前指向 的空间被释放。 分配的空间也是未初始化的。 的空间被释放。realloc分配的空间也是未初始化的。 分配的空间也是未初始化的
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
16.2
其他分配函数
除了malloc函数外,C标准库还提供了另外两个函数来分配 函数外, 标准库还提供了另外两个函数来分配 除了 函数外 堆内存: 函数和realloc函数。本节将对它们进行 函数。 堆内存:calloc函数和 函数和 函数 详细讨论,并与malloc函数进行比较。 函数进行比较。 详细讨论,并与 函数进行比较
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
16.3
动态数组的实现
借助堆管理来实现动态数组的基本思想就是动态地按需分配 要求多少内存就分配多少内存,根据需求, 。要求多少内存就分配多少内存,根据需求,使用分配 函数在堆上获取指定大小的内存空间, 函数在堆上获取指定大小的内存空间,最后将这块内存 空间的起始地址作为该数组的首地址。 空间的起始地址作为该数组的首地址。使用指针变量从 堆上动态分配空间的方法可以模拟实现动态数组, 堆上动态分配空间的方法可以模拟实现动态数组,即可 在运行期设定数组容量的数组。其基本代码步骤如下: 在运行期设定数组容量的数组。其基本代码步骤如下 元素类型名 * point = NULL; point = (元素类型名 *) malloc (数组容量 * sizeof(元素类型 元素类型名 数组容量 元素类型 名)); 或使用calloc,代码如下: 或使用 ,代码如下: 元素类型名 * point = NULL; point = (元素类型名 *) calloc (数组容量 sizeof(元素类型 数组容量, 元素类型名 数组容量 元素类型 名));
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
realloc函数 16.2.2 realloc函数
如果执行成功, 函数返回新空间的首地址。 如果执行成功,realloc函数返回新空间的首地址。如 函数返回新空间的首地址 果失败,则返回NULL。当p的值为 果失败,则返回 。 的值为NULL时,即 时 的值为 realloc(NULL, n),其等效于 ,其等效于malloc(n);当n的值为 ; 的值为 0时,即realloc(p, 0),其等效于 时 ,其等效于free(p)。 。 注意:使用malloc函数、calloc函数和 函数、 函数和realloc函数分 注意:使用 函数 函数和 函数分 配的内存空间都要使用free函数或指针参数为 函数或指针参数为NULL 配的内存空间都要使用 函数或指针参数为 函数来释放。 的realloc函数来释放。 函数来释放
北京源智天下科技有限公司
Fra Baidu bibliotek
联系方式:http://www.rzchina.net
calloc函数 16.2.1 calloc函数
calloc函数的功能与 函数的功能与malloc函数相似,都从堆上分配内存。 函数相似, 函数的功能与 函数相似 都从堆上分配内存。 其函数声明如下: 其函数声明如下: void *calloc(int n, int size); 函数返回值为void型指针。如果执行成功,函数从堆上获得 型指针。如果执行成功, 函数返回值为 型指针 size×n的字节空间,并返回该空间的首地址。如果执行 的字节空间, × 的字节空间 并返回该空间的首地址。 失败,函数返回NULL。该函数与 失败,函数返回 。该函数与malloc函数一个显著的 函数一个显著的 不同是, 函数得到的内存空间是经过初始化的, 不同是,calloc函数得到的内存空间是经过初始化的,其 函数得到的内存空间是经过初始化的 内容为全0。 函数适合为数组申请空间, 内容为全 。calloc函数适合为数组申请空间,可以将 函数适合为数组申请空间 size设置为数组元素的空间长度,将n设置为数组容量。 设置为数组元素的空间长度, 设置为数组容量。 设置为数组元素的空间长度 设置为数组容量
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
malloc函数和memset函数 函数和memset 16.1.1 malloc函数和memset函数
该函数可以将内存空间按字节为单位置为指定的字符c。 该函数可以将内存空间按字节为单位置为指定的字符 。其 为要清零的内存空间的首地址, 为要设定的值 为要设定的值, 中,p为要清零的内存空间的首地址,c为要设定的值,n 为要清零的内存空间的首地址 为被操作的内存空间的字节长度。如果要使用memset清 为被操作的内存空间的字节长度。如果要使用 清 0,变量 的实参要为 。malloc函数和 的实参要为0。 函数和memset函数的操 ,变量c的实参要为 函数和 函数的操 作语句一般如下: 作语句一般如下: 01 int * p = NULL; /* p也可以为其他类型指针 也可以为其他类型指针 */ 02 p = (int *) malloc (sizeof(int)); 03 if (NULL == p) 04 printf(“Can’t get memory!\n”); 05 memset(p, 0, sizeof(int));
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
malloc函数和memset函数 函数和memset 16.1.1 malloc函数和memset函数
需要注意的是, 需要注意的是,malloc函数分配的内存空间是未初始化的 函数分配的内存空间是未初始化的 因此,一般在使用该内存空间时, 。因此,一般在使用该内存空间时,要调用另一个函数 memset来将其初始化为全 。memset函数的函数声明 来将其初始化为全0。 来将其初始化为全 函数的函数声明 如下: 如下: void * memset(void * p, int c, int n);
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
free函数 16.1.2 free函数
从堆上获得的内存空间在程序结束后, 从堆上获得的内存空间在程序结束后,系统不会自动将其释 需要程序员自己来管理。一个程序结束时, 放,需要程序员自己来管理。一个程序结束时,必须保 证所有从堆上获得的空间已被安全释放, 证所有从堆上获得的空间已被安全释放,否则会导致内 存泻泄露。例如范例16-1就会发生内存泄露。如何避免 就会发生内存泄露。 存泻泄露。例如范例 就会发生内存泄露 内存泄露是堆内存管理的一个重点和难点。 内存泄露是堆内存管理的一个重点和难点。 free函数可以实现释放内存的功能。其函数声明为: 函数可以实现释放内存的功能。其函数声明为: 函数可以实现释放内存的功能 void free(void * p);
北京源智天下科技有限公司
联系方式:http://www.rzchina.net
malloc函数和memset函数 函数和memset 16.1.1 malloc函数和memset函数
malloc函数可以从堆上获得指定字节数的内存空间,其函 函数可以从堆上获得指定字节数的内存空间, 函数可以从堆上获得指定字节数的内存空间 数声明如下: 数声明如下: void * malloc(int n); 其中形参n为要求分配的字节数。如果函数执行成功, 其中形参 为要求分配的字节数。如果函数执行成功, 为要求分配的字节数 malloc函数返回获得的内存空间的首地址;如果函数执 函数返回获得的内存空间的首地址; 函数返回获得的内存空间的首地址 行失败,那么返回值为NULL。由于 行失败,那么返回值为 。由于malloc函数值的类型 函数值的类型 型指针, 为void型指针,因此可以将其值类型转换后赋值给任意 型指针 类型指针, 类型指针,这样就可以通过操作该类型指针来操作从堆 上获得的内存空间。 上获得的内存空间。
第16章 16章
堆管理
通过本章的学习,需要掌握以下知识点: 通过本章的学习,需要掌握以下知识点: 理解堆的概念; 理解堆的概念; malloc函数和 函数和free函数的正确使用; 函数的正确使用; 函数和 函数的正确使用 memset函数的正确使用; 函数的正确使用; 函数的正确使用 calloc函数和 函数和realloc函数的正确使用; 函数的正确使用; 函数和 函数的正确使用 动态数组的管理和使用。 动态数组的管理和使用。
相关文档
最新文档