C语言(内存管理)

初始化内存空间

#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个二进制位】

猜你喜欢

转载自www.cnblogs.com/TianLiang-2000/p/12712454.html