初始化内存空间
#include <malloc.h>导入头文件
memset:使用一个常量字节填充内存空间
memcpy:拷贝内存空间
memmove:拷贝内存空间
memcmp:比较内存空间
memchr:在内存空间中搜索一个字符
若是处理字符串,将‘mem’开头改为‘str’,因为这是针对处理内存空间的;
灵活的内存管理方式
void *malloc(size_t size);//申请动态内存空间;(void 可以转换成任意类型是数据) //作用:向系统申请分配size个字节的内存空间,并返回一个指向这块空间指针例如: int *ptr=(int *)malloc(sizeof(int));//堆内存 void free(void *ptr);//释放动态内存空间; //因为动态申请的内存空间存在于堆上,所以如果不主动释放,则他会保存到程序关闭 //作用:释放ptr参数指向的内存空间,前提是该空间必须是有malloc,calloc,realloc函数申请的 //注:若参数是NULL,不执行任何操作。该函数不会修改ptr参数的值,所以调用之后依旧指向原来的地方 //实际上只是释放该地址的使用权,该地址所储存的数据其实没有被销毁;所以C语言中定义变量后必须初始化,否者数据就是变量地址上次使用的垃圾数据; void *calloc(size_t nmemb,size_t size);//申请并初始化一系类内存空间 //作用:申请nmemb个长度为 saze 的连续内存空间并且初始化为0;即: int *ptr=(int *)calloc(N,sizeof(int));//等价于 int *ptr=(int *)malloc( N * sizeof(int) ); memset( ptr , 0 , N * sizeof(int) ); void *realloc(void *ptr , size_t size );//重新分配内存空间(一般应用于动态加长) //作用:ptr指向重新分配的一块空间,将旧内存块释放并将数据拷贝在新的空间中 若:ptr参数为NULL,相当于调用malloc(size); //size 参数为0;并且ptr参数不为NULL,相当于调用 free(ptr)
注:如果 ptr 参不为NULL;则他必须是由 malloc, calloc,realloc 动态分配的空间
内存泄漏
因为为程序分配的空间被动态申请完,导致程序被杀
1、隐式内存泄漏 (用完内存块没有及时用 free 函数释放);
2、丢失内存块地址(丢失分配的地址,使其无法在用完之后及时释放)
内存的布局规律
由低地址到高地址存储:代码段->数据段->bss段->堆->栈
代码段:通常指用来存放程序执行代码的一段区域,并且在程序运行前就已经确定;
数据段:通常用来存放已经初始化的全局变量和局部静态变量;
bss段:通常用来存放程序中未初始化的全局变量的一块内存区域。(运行前将被自动初始化为0)
堆:用于存放进程运行中被动态分配的内存段,大小不固定,可动态扩缩,(动态申请和释放内存)
栈:函数执行的内存区域,通常和堆共享同一片区域(局部变量,函数的参数,函数的返回值)
堆和栈的区别:
申请:堆手动申请;栈由系统自动分配;
释放:堆手动申请;栈由系统自动释放;
生存周期:堆由动态申请到主动释放为止;(函数间局部变量可访问;即,返回给主调函数,主调函数还可以继续使用)栈由函数调用开始到函数返回时结束;(函数间局部变量不可相互访问)
发展方向:堆和其他区段一样,都是从低地址到高地址发展;
栈则相反,由高地址向低地址发展 (压栈);
内存池
释放动态申请的内存时;先将其放入内存池,在下次动态申请内存时就可以直接把内存池中的内存拿出来用;
因为动态申请内存时,程序要访问内存,使的效率较低;
(可用单链表实现)
—————————————————————————————————————————————————————
位域
指定占用的二进制数(一字节占八个二进制位);(只有 int 型和 boolean 类型支持位域)
unsigned int a:2;这里声明不能带符号,且占两个二进制位=>最多能表示到3
注:位域的宽度不能超过他所依据类型的长度【上面的 int 就最多只占32个二进制位】