【C】动态内存函数——大全(基本,简洁,包教会,适合初学)

 前言:大家好,这里是YY;此篇博客主要是动态内存函数的知识点;包含free】【malloc】【calloc】【realloc】【柔性数组

PS:创作不易,每个知识点都有例题或者图帮助理解;如果对你有帮助,希望能够得到您的关注,赞,收藏,谢谢!  

目录

一.动态内存函数介绍

内存函数的头文件:

1.free

2.malloc

情景1:申请内存空间失败——返回空指针

情景2:动态内存的底层原理

情景3:释放动态内存空间后还要把p置为空指针——防止野指针

3.calloc

情景1:calloc开辟的值是0,而malloc开辟的空间没有初始化是随机值

4.realloc

情景1:realloc开辟失败,与malloc一样,返回的是NULL 

情景2:realloc调整空间,分类讨论(内存空间足够与否)

情景4:realloc调整空间时,申请内存的起始位置是空指针

二.常见的动态内存错误

情景一:对空指针进行解引用

情景二:对动态开辟空间的越界访问

情景三:对非动态开辟的内存使用free释放 / 对同一块动态开辟的内存多次释放

情景四:使用free释放一块动态开辟内存的一部分

情景五:未对动态开辟内存使用free释放——造成内存泄漏

三.几个经典的笔试题

例题1:

例题2:

例题3:内存泄漏

例题4:非法访问(野指针)

四.C/C++程序的内存开辟

五.柔性数组

柔性数组的两种写法: 

1.柔性数组的特点

2.用另一种方式实现柔性数组功能

两种方式的对比: 


一.动态内存函数介绍


内存函数的头文件:

include<stdlib.h>

1.free

free函数用来释放动态开辟的内存。

  • 如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的
  • 如果参数ptr是NULL指针,则函数什么事都不做 

使用场景: 

int num=10;
int* p=NULL;
free(p);
p=NULL;

2.malloc

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针

  • 如果开辟成功,则返回一个指向开辟好空间的指针
  • 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要检查
  • 返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定
  • 如果参数size为0,malloc的行为是未定义的,取决于编译器 

情景1:申请内存空间失败——返回空指针


情景2:动态内存的底层原理

  1. 局部变量特点,进函数时创建,出函数时销毁

  2. 局部变量放在栈区

  3. 动态内存分配放在堆区不会自动摧毁,直到程序退出才释放。(易造成爆内存

     


情景3:释放动态内存空间后还要把p置为空指针——防止野指针

释放动态内存空间后,p还会记得一个地址(野指针)

free(p);
p=NULL;

3.calloc

  •  函数的功能是为num个大小为size的元素开辟一块空间,并把空间每个字节都初始化为0
  • 与malloc的区别只在于calloc会在返回地址之前把申请的空间每个字节全初始化为0

       相当于calloc=malloc+memset


情景1:calloc开辟的值是0,而malloc开辟的空间没有初始化是随机值


4.realloc

  • ptr是要调整的内存地址
  • size是要调整后的新大小
  • 返回值为调整之后的内存起始位置
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间 

情景1:realloc开辟失败,与malloc一样,返回的是NULL 

解决方案:使用时也要判断,创建临时指针ptr来判断,如果成功再给p指针

 


情景2:realloc调整空间,分类讨论(内存空间足够与否)

  1. 当内存空间足够时,拓展方法:就直接原有内存之后直接追加空间,原来空间数据不发生变化,这样函数返回的是原内存地址
  2. 当内存空间不足时,拓展方法:在堆空间上另外找一个合适的连续空间来使用,这样函数返回的是一个新的内存地址


情景4:realloc调整空间时,申请内存的起始位置是空指针

申请内存起始位置是空指针时:等价于malloc

int*p=(int*)realloc(NULL,40);等价于malloc(40)

二.常见的动态内存错误


情景一:对空指针进行解引用

解决方法:判断指针是否为空


情景二:对动态开辟空间的越界访问


情景三:对非动态开辟的内存使用free释放 / 对同一块动态开辟的内存多次释放

解决方法:把p指针置为NULL,则无影响


情景四:使用free释放一块动态开辟内存的一部分

在释放时,p指针已经移动,指向的不再是动态内存空间的起始位置

解决方法:

  • 创建一个新指针ptr拷贝起始地址,遍历/移动指针时时用新指针ptr
  • 不改变"p指向的是动态内存空间的起始地址"的写法

       


情景五:未对动态开辟内存使用free释放——造成内存泄漏

指针会变成野指针,造成非法访问

 


三.几个经典的笔试题

例题1:

例题2:

例题3:内存泄漏

例题4:非法访问(野指针)

四.C/C++程序的内存开辟


五.柔性数组

C99中,结构中的最后一个元素允许是未知大小的数组


柔性数组的两种写法: 

有些编译器无法编译时,可以改成:


1.柔性数组的特点

  • 结构中的柔性数组成员前面必须至少有一个其他成员
  • sizeof返回这种结构大小,不包括柔性数组的内存

        

  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

       

  • 柔性数组的体现——可以更改数组的大小

       


2.用另一种方式实现柔性数组功能

法二:“单独malloc块空间,在此之上realloc”


两种方式的对比: 

  • 第一种方式好处:方便内存释放
  • 第二种方式好处:有利于访问速度(连续的内存有益于提高访问速度)
  • 第二种方式坏处:要进行两次释放,容易造成内存泄漏

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YY的秘密代码小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值