C语言动态内存管理

C语言动态内存管理,第1张

hello hello,本篇文章将讲解关于C语言动态内存管理的知识,动态内存管理是一个很重要的知识点,希望这篇文章能让各位uu们对知识的认识和理解更深一步。

目录

为什么有动态内存分配

动态内存分配函数

1.malloc

2.free

3.calloc

4.realloc

常见的动态内存错误

柔性数组


一、什么有动态内存分配

        在我们编程的时候,往往会涉及到开辟空间的问题,像定义数组时我们会设定数组的大小,也就是我们向内存空间申请的空间,但是这块空间的大小是固定死的,如果存入数据不多就会造成空间浪费,数据过多会放不下,这里就会有uu说,那我在知道到底要多大空间之后再定义数组就好啦,但是在变成解决问题时,这些信息不一定是能准确地知道的,而且在编程过程中,所需的内存空间可能是会发生变化的,所以这个时候,动态内存分配的作用就凸现出来了。

        使用动态内存分配可以随时向内存申请所需要的大小,可以按需控制空间大小,灵活性更高,空间利用率实现最大化(现阶段)。

二、动态内存分配函数

使用动态分配函数向内存申请的空间是位于堆区的

我们常用的内存区域的分块如下图所示

        1. malloc  

函数原型:void *malloc( size_t size );

函数功能:向内存的堆区申请指定字节大小的空间

  • size表示要开辟空间的字节数
  • void* 表示返回类型为空指针
  • 如果申请空间成功,将会返回指向这块空间的首地址,如果申请空间失败,将会返回NULL(空指针进行解引用是非法的,我们在使用的时候会对返回值进行强制转换)
  • 基于上述,我们在 *** 作返回的指针时需要先判断其是否为空
  • size=0这种情况是标准未定义的,结果取决于编译器

        2. free

函数原型:void free( void *memblock );

函数功能:将动态开辟的内存释放,还给 *** 作系统

  • membolck表示使用动态开辟函数申请的空间的地址指针
  • void表示free函数没有返回值
  • free一般都是与动态开辟函数malloc、calloc、realloc配套使用
  • 要释放动态开辟的空间,那就一定得得到这块空间的首地址,所以使用函数开辟空间得到得指针不能随意改动
  • free之后,这块空间还给了 *** 作系统,但是指针指向的地址没有发生改变,也就是说,此时原来指针成为了野指针,需要将其置空
  • 如果动态开辟的内存不使用free进行释放,会有内存泄漏的风险
  • 如果传入的指针为NULL,那么free啥都不干,如果不是指向动态内存的指针,这种行为是标准未定义的

        3. calloc

函数原型:void *calloc( size_t num, size_t size );

函数功能:向内存的堆区申请指定字节大小的空间,并将该块空间初始化为0

  • num表示一个数据的个数
  • size表示一个数据类型所占字节大小
  • void*表示函数返回类型为空指针(注意事项同malloc)
  • calloc的功能约等于malloc加上memset
  • 与malloc的相同点:都是用来开辟动态内存空间的
  • 区别:两个函数的参数不同
  • 本质上的区别不大,看个人需求选择使用

        4. realloc

函数原型:void *realloc( void *memblock, size_t size );

函数功能:调整所开辟空间的大小

  • memblock表示需要调整的空间的起始地址
  • size表示调整后整个空间所占字节数
  • void*表示函数返回值是空指针(注意事项与malloc相同)
  • realloc扩容存在两种情况:如果要扩大空间后面的空间满足需要,可以直接在原地进行扩容,那么就直接返回原来的起始地址
  • 如果要扩大空间后面的空间不能满足需要,那么realloc会在内存的堆区寻找一块足够大的空间开辟,并且将原来内存空间的内容拷贝过来,释放掉原来的空间,并返回当前空间的首地址
  • 将空间缩小就不存在你上述情况了

三、常见的动态内存错误

        1. 对NULL的解引用 *** 作;(在使用函数进行内存开辟后要进行判空之后再使用)

        2. 对动态开辟空间的越界访问;(对空间进行访问时,自己要想明白内存的边界)

        3. 对非动态开辟的空间使用free释放空间;

        4. 使用free释放一部分动态开辟的空间;(使用函数开辟空间得到的指针不能随意改动)

        5. 对同一块动态空间进行多次释放;

        6. 忘记释放动态开辟的内存空间。

切记,动态开辟的内存空间一定要释放,且正确地释放

四、柔性数组

C99标准引入了柔性数组的概念,什么是柔性数组呢?

结构体变量最后一个成员是一个未指定大小的数组,这个数组就是柔性数组

struct S1
{
    int i;
    int arr[];//这就是柔性数组
};

柔性数组的特点:

  • 在计算含有柔性数组的结构体大小的时候,不计算柔性数组的大小
  • 柔性数组前面至少有一个其他成员变量
  • 要使用malloc进行动态内存分配,且申请的空间大小要大于结构体的大小,后面剩余的空间就全部是柔性数组的了
  • 如果空间不够用,可以使用realloc扩容
  • 只能放在结构体的最后才叫柔性数组

以上就是动态内存的全部分享了,欢迎各位uu指正~

        

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/874877.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存