动态分配内存和链表

上传人:ji****72 文档编号:46511777 上传时间:2018-06-27 格式:PDF 页数:43 大小:373.56KB
返回 下载 相关 举报
动态分配内存和链表_第1页
第1页 / 共43页
动态分配内存和链表_第2页
第2页 / 共43页
动态分配内存和链表_第3页
第3页 / 共43页
动态分配内存和链表_第4页
第4页 / 共43页
动态分配内存和链表_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《动态分配内存和链表》由会员分享,可在线阅读,更多相关《动态分配内存和链表(43页珍藏版)》请在金锄头文库上搜索。

1、中国移动互联网研发培训专家中国移动互联网研发培训专家千锋千锋嵌嵌入式入式学院学院C C语言培语言培训训千锋千锋嵌嵌学院学院 语言培语言培-动态分配内存 Author:Richard.zhang源自清华 值得信赖源自清华 值得信赖中国移动互联网研发培训专家动态分配内存的使用场合动态分配内存的使用场合需要使用规模较大的内存,但是不能预先确定所需 的容量 规模较大:K、M级别 不能预先确定:只有在运行时刻,才能根据要处理的数据 内容确定其容内容确定其容量源自清华 值得信赖2中国移动互联网研发培训专家静态、动态分配内存的比较静态、动态分配内存的比较静态分配静态分配动态分配动态分配静态分配静态分配动态分

2、配动态分配适用场合小内存,可以预先确定容量大内存,不能以预先确定容量一般规模K级以内K级以上般规模K级以内K级以上语法char buf512;char *p = malloc(2000000);内存位置全局数据区 - 全局变量 栈部变堆 栈- 局部变量是否需要释放不需要需要技术要求简单相对复杂技术要求简单相对复杂源自清华 值得信赖3中国移动互联网研发培训专家malloc函数malloc函数#include void * malloc(size_t n);参数:n是要申请的内存容量(字节) 返回值所分配内存的首地址返回值:所分配内存的首地址源自清华 值得信赖4中国移动互联网研发培训专家例1:分配

3、大数组例1:分配大数组分配个可以容纳100000个整型数据的内存空间分配一个可以容纳100000个整型数据的内存空间int *array = (int *)malloc(100000 * sizeof(int);注意注意:1.内存容量 = 元素个数 * 元素容量 为提高可移植性元素容量使用 if获取2.为提高可移植性,元素容量使用sizeof获取源自清华 值得信赖5中国移动互联网研发培训专家例2:大容量结构体数组例2:大容量结构体数组分配一个包含N个结构体变量的数组 struct test int a;int a; char b; int c10; ;struct test * p = (st

4、ruct test *)malloc(N * sizeof(struct test);源自清华 值得信赖6中国移动互联网研发培训专家free函数free函数在不再需要使用动态申请的内存时,将其及时释放。#include void free(void * p);p是要释放的首地址源自清华 值得信赖7中国移动互联网研发培训专家动态分配的补充说明动态分配的补充说明内存空间大小是在运行时确定的变量动态分配的内存空间在未释放之前均可以被引用,动态分配的内存空间在未释放之前均可以被引用, 其生命期在整个程序运行期间有效源自清华 值得信赖8中国移动互联网研发培训专家堆和栈堆和栈栈进程地址空间进程地址空间堆代

5、码段数据段源自清华 值得信赖9中国移动互联网研发培训专家malloc函数的实现机制malloc函数的实现机制在堆中寻找一块空闲空间分配原则最先适合分配方法分配原则最先适合分配方法一个进程使用一个堆,由操作系统管理源自清华 值得信赖10中国移动互联网研发培训专家free机制总结free机制总结并不是真正的释放,只是将内存块标记为可用。问题1:释放内存后,系统显示的可用内存数会发 生改变吗?生改变吗 问题2:释放的内存还可以引用吗?源自清华 值得信赖11中国移动互联网研发培训专家非常规使用非常规使用(1)当申请0个字节时会出现什么情况 例如: int *p; p = (int *)malloc(0

6、);p; (2)释放一个非动态内存申请的空间 例如:例如 int array10, *p; p = array; py; free(p);源自清华 值得信赖12中国移动互联网研发培训专家两种内存分配的比较两种内存分配的比较动态分配内存和非动态分配内存的比较非动态分配内存非动态分配内存动态分配动态分配内存内存非动态分配内存非动态分配内存动态分配动态分配内存内存大小在编译时确定大小在运行时确定大小在编译时确定大小在运行时确定由编译器分配由操作系统参与分配由编译器分配由操作系统参与分配分配在数据段和栈内在堆内分配在数据段和栈内在堆内由操作系统自动释放手动显式释放源自清华 值得信赖13中国移动互联网研

7、发培训专家memset函数概念memset函数概念如果需要将一块内存设置为同一个值的时候,需要如果需要将块内存设置为同个值的时候,需要 使用memset函数。例如: 分配一个缓冲区将该缓冲区内的值清零分配个缓冲区,将该缓冲区内的值清零源自清华 值得信赖14中国移动互联网研发培训专家memset函数原形memset函数原形void memset(void *s, int n, size_t size);(,_); s:需要设置内存的首地址 n:需要被设置的值n:需要被设置的值 size:需要设置的字节数源自清华 值得信赖15中国移动互联网研发培训专家memset函数实例memset函数实例#in

8、clude int main() char s10; memset(void *)s a 10);memset(void *)s, a, 10); s10 = 0; printf(“%sn” s);printf( %sn , s); return 0; 输出结构为:aaaaaaaaa源自清华 值得信赖16中国移动互联网研发培训专家综合实例综合实例使用memset函数和malloc函数实现一个calloc函 数数源自清华 值得信赖17中国移动互联网研发培训专家memset函数实例memset函数实例#include int main() char s10; memset(void *)s a 1

9、0);memset(void *)s, a, 10); s10 = 0; printf(“%sn” s);printf( %sn , s); return 0; 输出结果为:aaaaaaaaa源自清华 值得信赖18中国移动互联网研发培训专家memcpy函数概念memcpy函数概念当需要在两块内存之间进行数据拷贝的时候需要使 用memcpy函数用memcpy函数 其原形为: void * memcpy(void *dest, const void * src,void memcpy(void dest, const void src, size_t n); dest:复制到目的地址复制到目的 s

10、rc:复制的源地址 n:需要复制的字节数源自清华 值得信赖19中国移动互联网研发培训专家memcpy函数实例memcpy函数实例#include int main() char s = “hello”, d10; memcpy(d s 5);memcpy(d, s, 5); d5 = 0; printf(“%s” d);printf( %s , d); return 0; 运行结果:hello源自清华 值得信赖20中国移动互联网研发培训专家替代函数替代函数void bzero(void *s, size_t n);(,_);void bcopy(void * dest const void *

11、 src size tvoid bcopy(void dest, const void src, size_t n);源自清华 值得信赖21中国移动互联网研发培训专家其它内存块操作的函数其它内存块操作的函数memccpy(拷贝内存内容) 定义函数 void * memccpy(void *dest, const定义函数 void memccpy(void dest, const void * src, int c,size_t n); 函数说明 memccpy()用来拷贝src所指的内存内函数说明 memccpy()用来拷贝src所指的内存内 容前n个字节到dest所指的地址上。与memcpy

12、() 不同的是,memccpy()会在复制时检查参数c是不同的是,memccpy()会在复制时检查参数c是 否出现,若是则返回dest中值为c的下一个字节地 址。址。 返回值为0表示在src所指内存前n个字节中没有 值为c的字节。源自清华 值得信赖值为c的字节。22中国移动互联网研发培训专家其它内存块操作的函数其它内存块操作的函数memcmp(比较内存内容) 相关函数 bcmp, 定义函数 int memcmp (const void *s1,const void *s2 size t n);*s2,size_t n); 函数说明 memcmp()用来比较s1和s2所指的内存区间前 n个字符。

13、字符串大小的比较是以ASCII码表上的顺序来决 定,次顺序亦为字符的值。memcmp()首先将s1第一个 字符值减去s2第一个字符的值,若差为0则再继续比较下 个字符,若差值不为0则将差值返回。例如,字符串“Ac“个字符,若差值不为0则将差值返回。例如,字符串 Ac 和“ba“比较则会返回字符A(65)和b(98)的差值(33)。 返回值 若参数s1和s2所指的内存内容都完全相同则返回 0值1若大于 2则返回大于0的值1若小于 2则返回0值。s1若大于s2则返回大于0的值。s1若小于s2则返回 小于0的值。源自清华 值得信赖23中国移动互联网研发培训专家其它内存块操作的函数其它内存块操作的函数

14、memmove(拷贝内存内容) 定义函数 void * memmove(void *dest,const定义函数 void memmove(void dest,const void *src,size_t n); 函数说明 memmove()与memcpy()一样都是用函数说明 memmove()与memcpy()样都是用 来拷贝src所指的内存内容前n个字节到dest所指 的地址上。不同的是,当src和dest所指的内存区的地址上。不同的是,当src和dest所指的内存区 域重叠时,memmove()仍然可以正确的处理, 不过执行效率上会比使用memcpy()略慢些。不过执行效率上会比使用m

15、emcpy()略慢些。源自清华 值得信赖24中国移动互联网研发培训专家需要注意的问题需要注意的问题以上函数需要使用的头文件为string.h以上函数需要使用的头文件为stg进行内存块复制的时候要注意目的地址和源地址交进行内存块复制的时候要注意目的地址和源地址交 叉的问题源自清华 值得信赖25中国移动互联网研发培训专家Section 2:链表Section 2:链表源自清华 值得信赖中国移动互联网研发培训专家链表的概述链表的概述struct node int node; /* 数据域,存储结点的值 */ struct node * next;struct node next; ;源自清华 值得信

16、赖中国移动互联网研发培训专家链表示意图链表示意图value 1value 2value 3value 4 NULL源自清华 值得信赖中国移动互联网研发培训专家处理链表使用的函数处理链表使用的函数动态申请内存:void * malloc(size_t n);释放动态内存:void free(void *); 释放动态内存: o dee( o d );源自清华 值得信赖中国移动互联网研发培训专家插入一个结点插入一个结点struct node *p = a.next = p; /* 连接a结点和b结点 */ ae tp; / 连接a结点和b结点 / b.next = /* 连接b结点和c结点 */源自清华 值得信赖中国移动互联网研发培训专家删除一个结点删除一个结点struct node *p = a.next = b.next; /* 连接a结

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号