1)内存管理的基本概念
内存管理是指软件运行的是后对计算机内存资源的分配和使用技术。其最主要的目的是如何高效、快速的分配,并且在适当的是很释放和回收内存资源。
①内存分配方式、内存分配方式有三种:
a、从静态存储区域分配。内存在程序编译的是很就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
b、在栈上创建。在执行函数是,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
c、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多稍等内存,程序员自己负责在核实用free或delete释放内存。动态内存的生命周期由我们决定,使用非常灵活,但问题也多。
2)内存分区
BSS段:通常是指用来存放程序中未初始化的全局变量和静态变量。
数据段:通常是指用来存放程序中已经初始化的全局变量和静态变量的一块内存区域。
代码段:通常是指用来存放程序执行代码的一块内存区域。
堆: 用于存放进程运行中被动态分配的内存段,大小不固定,可动态扩张或缩减。
栈: 栈又称堆栈,是用户存放程序临时创建的局部变量,也就是我们函数“{}”中定义的变量(但不包括static声明的变量)
3)常见内存分配函数
①为什么要进行动态内存分配?
以数组为例:一个数组的元素时存储于内存中连续的位置的,当数组被声明时其所需要的内存在编译的时候也已经被分配。但是有些情况下使用这种静态分配方式是不方便的,例如使用数组在存储班级中所有学生的成绩,但是不同班级的学生的数量是不同的,。
优点:简单
缺点:声明中引入了限制,如果程序需要使用的元素超过声明的长度,怎么办?
②常见动态分配内存分配函数
c语言中提供了三个动态分配内存的函数:malloc、calloc、realloc
a)malloc:使用的方法 void *malloc(unsigned size),其中size是指分配内存的字节。
void *malloc(unsigned size),包含在函数stdlib.h中,作用是在内存的堆区分配一个大小为size的连续空间,如果分配内存成功,函数返回新分配内存的首地址,否则返回NULL,
注意:鉴于上述这点,一般在写程序需要判断分配内存是否成功。
如下:
int *p;
p=(int *)malloc(sizeof(int));
if(p!=NULL){
//需要执行的代码块
}else{
//打印分配内存不成功的出错信息
}
代码:
void main(){
int *p=(int *)malloc(4*sizeof(int));
if(p!=null){
//申请成功依次赋值
*p=10;
*(p+1)=100;
*(p+2)=1000;
*(p+3)=10000;//存放了四个整数
}else{
//申请失败
printf("内存申请失败!\n");
}
//循环打印每一个值
for(int i=0;i<4;i++){
printf("%d\t",*(p+i));
}
}
b)calloc
格式:calloc(块数,长度)
代码:
//分配了4块,每一块内存长度为4的内存空间
//它们分配的地址是连续的
int *p=(int *)calloc(4,sizeof(int));
if(p!=NULL){
*p=10;
*(p+1)=100;
*(p+2)=1000;
*(p+3)=10000;
}else{
printf("内存申请失败!\n");
}
//输出结果为:10 100 1000 10000
calloc它可以帮我们自动初始化为0
c)realloc 可以给已经存在的空间扩充大小
p=realloc(p,40*sizeof(int));