C语言入门与提高5_第1页
C语言入门与提高5_第2页
C语言入门与提高5_第3页
C语言入门与提高5_第4页
C语言入门与提高5_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言入门与提高-51内存存储结构1、栈区(stack)由编译器自动分配释放,存放函数的参数值,局部变量的值等。2、堆区(heap)一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。3、读写段 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放4、只读段常量字符串和函数体的二进制代码就是放在这里的。程序结束后由系统释放2用户进程不可见栈指针(高到低)全局变量和静态变量程序代码和只读数据0 xc00000000 x400000000 x08048000低到高3栈和堆栈:在函数调用

2、时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排 。4共享库两个进程共享相同物理页面中的共享库,当然,只有只读的部分是共享的,可读可写的部分不共享。使用共享库可以大大节省内存。比如libc,系统中几乎所有的进程都映射libc到自己的进程地址空间,而libc的只读部分在物理内存中只需要存在一份,就可以被所有进程共享,这就是“共享库”这个名称的由

3、来了。5动态内存分配堆区空间应用6为什么使用动态内存分配程序中需要动态分配一块内存时怎么办呢?可以像以前那样定义一个变长数组。但这种方法不够灵活,C89要求定义的数组是固定长度的,而程序往往在运行时才知道要动态分配多大的内存。进程有一个堆空间C标准库函数malloc可以在堆空间动态分配内存,动态分配的内存用完之后可以用free释放,更准确地说是归还给malloc,这样下次调用malloc时这块内存可以再次被分配7malloc和free#include void * malloc(size_t size);返回值:成功返回所分配内存空间的首地址,出错返回NULLvoid free(void *p

4、ointer);free(p);之后,p所指的内存空间是归还了,但是p的值并没有变,p现在指向的内存空间已经不属于用户,换句话说,p成了野指针,为避免出现野指针,我们应该free(p)之后手动置p = NULL;8使用动态分配的内存char * p;p=malloc(sizeof(char)*100);if(p=NULL) printf(”errorn”); return -1;strcpy(p,”hello”);free(p);9练习用动态分配内存方法重新实现char *strcat(const char *str1,const char *str2)返回动态分配内存首地址10calloc和

5、reallocVoid *calloc( size_t num, size_t size);分配num个元素的内存空间,每个元素占size字节,并且calloc负责把这块内存空间用字节0填充Void *realloc(void * ptr, size_t new_size);把原内存空间的指针ptr传给realloc,通过参数size指定新的大小(字节数),返回新内存空间的首地址,并释放原内存空间。新内存空间中的数据尽量和原来保持一致,如果size比原来小,则前size个字节不变,后面的数据被截断,如果size比原来大,则原来的数据全部保留,后面长出来的一块内存空间未初始化11练习1、用cal

6、loc函数分配int类型空间,对其赋值和输出2、验证realloc函数是在原来空间的基础上扩大,还是重新分配更大的空间,把原来的数据复制过去12常见的动态内存错误1.忘记检查内存是否分配成功2.访问越界3.释放并非动态分配的内存4.释放动态内存的一部分5.释放动态内存后继续使用13内存泄漏内存动态分配后,当它未不再被使用时未被释放.调用malloc分配内存,则必须有free与之配对,分配一次就要释放一次,否则每次循环都分配内存,分配完了又不释放,就会慢慢耗尽系统内存,这种错误称为内存泄漏(Memory Leak)。另外,malloc返回的指针一定要保存好,只有把它传给free才能释放这块内存,

7、如果这个指针丢失了,就没有办法free这块内存了,也会造成内存泄漏。14链表动态申请的内存空间,实现使用连续空间head指针是链表的头指针,指向第一个节点,每个节点的next指针域指向下一个节点,最后一个节点的next指针域为NULL,在图中用0表示。15每个链表有一个头指针,通过头指针可以找到第一个节点,每个节点都可以通过指针域找到它的后继,最后一个节点的指针域为NULL,表示没有后继。数组在内存中是连续存放的,而链表在内存中的布局是不规则的,我们知道访问某个数组元素bn时可以通过基地址+n每个元素的字节数得到它地址,或者说数组支持随机访问,而链表是不支持随机访问的,只能通过前一个元素的指针域得知后一个元素的地址,因此只能从头指针开始顺序访问各节点。链表的特点16链表的操作创建链表结构体做节点头指针next指针连接下一个节点最后一个节点next指针为NULL17struct node int num; struct node * next;link p = malloc(sizeof *p)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论