动态内存的介绍(malloc/free/calloc/realloc)&&操作动态内存常见错误

动态内存函数介绍


  • 动态内存开辟函数:void* malloc(size_t size);
    注意:
    1. 如果开辟成功则返回一个指向开辟空间的指针
    2. 如果开辟失败返回 NULL 指针,因此malloc的返回值一定要做检查。
    3. 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定
    4. 如果 size 为 0,malloc 的行为是标准未定义的
  • 释放动态开辟的内存:void free(void* ptr);
    注意:
    1. 如果参数 ptr 指向的空间不是动态开辟的,那 free 函数的行为是未定义的。
    2. 如果参数 ptr 是 NULL 指针,则函数什么都不做。
  • 动态内存开辟:void* calloc(size_t num, size_t size);
    注意:
    1. 函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为 0
    2. 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0,但是malloc 的内存中由于没有初始化,内存中是上次存储的值。
    3. 用法更多的是利用 malloc 申请动态内存,然后手动初始化,calloc() 用的比较少
  • 动态内存扩容:void *realloc(void *mem_address, unsigned int newsize);
    注意:
    1. realloc 能够对 malloc / calloc 申请的内存进行扩容。
    2. 如果该内存后边的空间足够容纳扩容后的空间,就直接扩容
    3. 如果该内存后边的空间不够了,另外找一段连续的足够容纳的内存空间,把原内存空间的数据拷贝到新的空间,并且释放原有的内存空间。
    4. 第一个参数:要改变内存大小的指针名
    5. 第二个参数:新的大小(字节为单位)

动态内存常见错误
  1. INT_MAX 宏 21亿 大约2G,malloc( INT_MAX * 4 );开辟 8G 的内存,肯定不可以,返回空指针,空指针解引用是位定义行为,因此在引用之前判断,是否为空。
  2. free()
    • 必须搭配 malloc 系列函数来使用,否则将是未定义行为
    • 一次 malloc 两次 free,第二次 free 释放的不是动态内存,因此错误
      int* p = (int*)malloc(4);
      free(p);
      free(p); 
      
    • malloc 两次,free 一次,两次 malloc 相当于开辟了两块动态内存空间,而 p 最终指向的是第二块儿动态内存空间,释放 p 时候也仅仅释放了第二块儿动态内存,第一块儿并没有释放,所以导致内存泄露
      int* p = (int*)malloc(4);
      p = (int*)malloc(4);
      free(p);
      
    • 指针的加减,这时释放的内存不是动态内存,未定义行为
      int* p = (int*)malloc(40);
      p++;
      free(p);
      

猜你喜欢

转载自blog.csdn.net/qq_40860852/article/details/88202824