一、内存管理
1、程序分两部分
(1)没有运行的部分:存放在硬盘中
(2)正在运行的部分:存放在内存中
内存的分类:
2、栈
栈存放的是所有自动变量(局部变量)、函数形参,这个入栈和出栈是由系统自动完成的
3、堆
是由程序员自己管理的,在程序运行的过程中进行动态的分配。
4、栈和堆的区别
(1)管理方式不同:栈由系统自己管理,堆由程序员管理
(2)空间大小不同:栈的空间远小于堆的空间
(3)是否产生碎片:栈不会产生碎片,而堆会产生碎片
(4)增长方向不同:栈是由高到低,堆是由低到高
(5)分配方式不同:堆由malloc()函数完成,栈由alloc(),动态由编译器进行分配和释放;
(6)分配效率不同:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行。堆则是C函数库提供的,它的机制很复杂,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大的空间,如果没有足够大的空间(可能是由于内存碎片太多),就有需要操作系统来重新整理内存空间,这样就有机会分到足够大小的内存,然后返回。显然,堆的效率比栈要低得多
二、malloc函数
1、用途
在堆上分配空间,参数是要分配的空间大小(单位位字节)
2、分配单个变量
int *pa = (int *)malloc(sizeof(int)/sizeof(char));
返回值是一个指向分配空间的指针
if(NULL == pa)
{
printf(“分配空间失败\n”)
}
注意:要在分配完后加一句判断空间是否分配成功的判断放在分配失败出现野指针。
free(pa);
注意:每次空间使用完后都要用free释放,不然会造成内存泄漏。
4、分配二维数值的两种方式
1、连续空间的a[3][4]的二维数组:
int pa[4] = (int ()[4])malloc(sizeof(int)/sizeof(char)*3);
Free(pa);
2、不连续空间的a[3][4]的二维数组:
int **pa = (int **)malloc(sizeof(sizeof(int)/sizeof(char)*3);
Int i;
if(NULL == pa)
{
printf("分配空间失败\n");
}
for(i = 0 ; i < 3; i++)
{
pa[i] = (int *)malloc(sizeof(int)/sizeof(char)*4);
if(NULL == pa)
{
printf("分配空间失败\n");
}
}
for(i = 0 ; i < 3; i++)
{
free(pa[i]);
}
free(pa);
注意:在这里释放空间的时候不能先释放pa,不然pa[i]的地址就找不到了会产生内存泄漏。
三、free函数
1、功能:
释放在堆上申请的空间
2、参数
指向要释放空间的指针
3、例如
int *pa = (int *)malloc(sizeof(int)/sizeof(char));
free(pa);
四、fealloc函数
1、用途
用于对堆的空间进行扩大或缩小,
扩大的时候如果后面的空间不够会重新找一个长度够得内存空间改变原来的初始地址
2、例子
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *pa = (int *)malloc(sizeof(int)/sizeof(char));
if (NULL == pa)
{
printf("分配空间失败\n");
}
// 重新分配,使用新指针,不要使用原有的指针
int *p = (int*)realloc(pa, sizeof(int)/sizeof(char)*10);
if (NULL == p)
{
printf("分配空间失败\n");
}
pa = p;
free(p);
return 0;
}
五、calloc函数
1、功能和优点
它的主要优点是把动态分配的内存进行初始化,全部清零。
六、memset函数
1、功能
将s中当前位置后面的n个字节 用 c 替换并返回 s ,一般用于清零
2、例子
#include <stdio.h>
#include <string.h>
int main()
{
char buf[] = "dasdfdsdas";
printf ("memset之前的字符串:%s\n", buf);
memset(buf, 0, sizeof(buf)+1);
printf ("memset之后的字符串:%s\n", buf);
return 0;
}