C——内存管理总结

作用域

1.1 auto 自动变量
一般情况下代码块内部定义的变量都是自动变量(栈变量)。当然也可以显示的使用auto关键字。

1.2 register 寄存器变量
register int i;
把变量放到CPU的寄存器里面,代码执行效率会更高,但取不到变量的地址(&i会出错)。

1.3 extern 关键字
extern修饰全局变量glo_var时,表明glo_var可以被其他模块的函数使用。
extern修饰函数是,表明函数可以被其他模块的函数调用。

1.4 static关键字
static修饰的变量、函数的特点:
1、只初始化一次;
2、生命周期:从第一次调用开始,到main结束(整个进程运行期间有效)。

static修饰局部变量var时,表明var在函数调用结束时不销毁,但不能被函数外的其他函数使用。
static修饰全局变量glovar时,表明glovar不能够被其他模块的函数使用;
static修饰函数,表明函数不能够被其他模块的函数调用;

1.5 voltile 关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。
参考:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html

内存四区

这里写图片描述
这里写图片描述

2.1 代码区
代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。

2.2 静态区
所有的全局变量以及程序中的静态变量都存储到静态区。

2.3 栈区
栈stack,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。

2.4 堆区
堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。
堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

2.5 堆的分配和释放
三个堆内存分配函数:

1、void* malloc(unsigned size);

char* p;
p=(char*)malloc(20);
malloc用于申请一段新的地址,参数size为需要内存空间的长度。
malloc不能初始化所分配的内存空间,需调用函数memset自行初始化。

常见陷阱1:
这里写图片描述

常见陷阱2:

这里写图片描述

解决方案之二级指针:
这里写图片描述

2、void* calloc(size_t numElements, size_t sizeOfElement);

char* p;
p=(char*)calloc(20,sizeof(char));
与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,即在堆内存中申请numElements*sizeOfElement字节大小的连续地址空间。
calloc() 会将所分配的内存空间中的每一位自动初始化为零。

动态数组
这里写图片描述

3、void* realloc(void* ptr, unsigned newsize);

char* p;
p=(char*)malloc(sizeof(char)*20);
p=(char*)realloc(p,sizeof(char)*40);
realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度。
当缩小内存空间时:被缩小的那一部分的内容会丢失。
当扩大内存空间时:realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;如果数据后面的字节不够,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上.这句话传递的一个重要的信息就是数据可能被移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值