lecture13一高级指针 绳伟光 上海交通大学微纳电子学系 2017年04月18日 SHA ERS
lecture 13 —— 高级指针 绳伟光 上海交通大学微纳电子学系 2017年04月18日
内容 ■动态内存分配 2
动态内存分配 内容 2
动态存储分配 ■C的数据结构,包括数组,一般都是具有固定 尺寸的 固定尺寸的问题在于必须在编译时事先指定尺 寸,而指定的尺寸又未必合适 ( c还支持动态存储分配(dynamic storage allocation:即在运行时分配存储空间的能力 ■ 利用动态存储分配机制,我们可以设计能按需 增长内存空间的数据结构 动态存储分配主要用于字符串、数组和结构
动态存储分配 C的数据结构,包括数组,一般都是具有固定 尺寸的 固定尺寸的问题在于必须在编译时事先指定尺 寸,而指定的尺寸又未必合适 C还支持动态存储分配(dynamic storage allocation): 即在运行时分配存储空间的能力 利用动态存储分配机制,我们可以设计能按需 增长内存空间的数据结构 动态存储分配主要用于字符串、数组和结构 3
动态存储分配(续) 动态分配的数据结构可以组合在一起构成链表 ((lists),树(trees)以及其它复杂数据结构 动态存储分配是通过调用内存分配函数完成的 内存分配函数分布在头文件中 malloc:该函数分配一块空间,但不初始化 calloc:该函数分配一块空间,且初始化 realloc:该函数调整已分配的空间的大小 ■三个函数返回的都是void*指针,即泛化 (generic)的指针类型
动态存储分配(续) 动态分配的数据结构可以组合在一起构成链表 (lists), 树(trees)以及其它复杂数据结构 动态存储分配是通过调用内存分配函数完成的 内存分配函数分布在头文件中 malloc:该函数分配一块空间,但不初始化 calloc:该函数分配一块空间,且初始化 realloc:该函数调整已分配的空间的大小 三个函数返回的都是void*指针,即泛化 (generic)的指针类型 4
空指针(Null Pointers) 如果动态内存分配失败,会返回一个空指针 空指针的值是一个特殊值,可以和所有有效的 指针加以区分 ■必须检查动态内存分配函数的返回值是否是空 指针 p = ma11oc(10066); if (p =NULL /*allocation failed;take appropriate action*/ NULL是标准库中定义的一个宏,代表空指针值 5
空指针(Null Pointers) 如果动态内存分配失败,会返回一个空指针 空指针的值是一个特殊值,可以和所有有效的 指针加以区分 必须检查动态内存分配函数的返回值是否是空 指针 NULL是标准库中定义的一个宏,代表空指针值 p = malloc(10000); if (p == NULL) { /*allocation failed; take appropriate action*/ } 5
空指针(续) 判断内存分配返回的指针的精炼代码 if ((p malloc(10000))==NULL) /allocation failed;take appropriate action * 对于指针,if(p=NULL)可简写为if(p)…,同样, if(pI=NULL).可简写为if(p). 因此上述代码的进一步简化版本为: if(!(p=ma11oc(16008)){ /allocation failed;take appropriate action * 6
空指针(续) 判断内存分配返回的指针的精炼代码 对于指针,if (p == NULL) …可简写为if (!p) …,同样, if (p != NULL) …可简写为if (p) … 因此上述代码的进一步简化版本为: if ((p = malloc(10000)) == NULL) { /* allocation failed; take appropriate action */ } if (!(p = malloc(10000))) { /* allocation failed; take appropriate action */ } 6
动态分配的字符串 动态分配经常用于字符串的分配 ■字符串存储为字符数组的形式,很难预测数组 需要多长才能满足要求 通过对字符串动态分配,可以将分配空间的大 小留至程序运行时才决定
动态分配的字符串 动态分配经常用于字符串的分配 字符串存储为字符数组的形式,很难预测数组 需要多长才能满足要求 通过对字符串动态分配,可以将分配空间的大 小留至程序运行时才决定 7
用malloci为字符串分配内存 malloc函数的原型为: void *malloc(size t size); ■malloc?分配一块内存,并返回指向内存的指针 ■size t是C库中定义的一个无符号整数类型 ■为包含n个字符的字符串分配内存: p malloc(n 1); p被声明为char*类型的指针 ■每个字符需要1Byte的内存,还需加上末尾的空字符 ■ 有些程序员喜欢为malloc加上转型操作,实际上转型 操作不是必须的,因为void*可赋值给任意指针类型: p =(char *malloc(n 1);
用malloc为字符串分配内存 malloc函数的原型为: void *malloc(size_t size); malloc分配一块内存,并返回指向内存的指针 size_t是C库中定义的一个无符号整数类型 为包含n个字符的字符串分配内存: p = malloc(n + 1); p被声明为char *类型的指针 每个字符需要1 Byte的内存,还需加上末尾的空字符 有些程序员喜欢为malloc加上转型操作,实际上转型 操作不是必须的,因为void*可赋值给任意指针类型: p = (char *) malloc(n + 1); 8
用malloci为字符串分配内存(续) malloc返回的内存是未初始化的,所以p指向一段可 容纳n+1个字符的未初始化数组: 0 1 23 4 n ■可用strcpy为数组赋初值:strcpy(p,"abc"); a b 0 2 4 n 9
用malloc为字符串分配内存(续) malloc返回的内存是未初始化的,所以p指向一段可 容纳n+1个字符的未初始化数组: 可用strcpy为数组赋初值: strcpy(p, "abc"); 9
一个利用动态分配的字符串拼接函数 char *concat(const char *s1,const char *s2){ char *result; result malloc(strlen(s1)+strlen(s2)1); if (result =NULL) printf("Error:malloc failed in concat\n"); exit(EXIT FAILURE); ) strcpy(result,s1); strcat(result,s2); return result; p=concat("abc","def");结果为:p指向"abcdef'" 该函数不会修改任何源字符串 malloc返回的指针可作为函数返回值,因为其不会在 函数退出时销毁(如果永不消毁它,则出现内存泄漏)
一个利用动态分配的字符串拼接函数 char *concat(const char *s1, const char *s2) { char *result; result = malloc(strlen(s1) + strlen(s2) + 1); if (result == NULL) { printf("Error: malloc failed in concat\n"); exit(EXIT_FAILURE); } strcpy(result, s1); strcat(result, s2); return result; } p = concat("abc", "def");结果为:p指向"abcdef" 该函数不会修改任何源字符串 malloc返回的指针可作为函数返回值,因为其不会在 函数退出时销毁(如果永不消毁它,则出现内存泄漏) 10