0871-64605728
您当前位置:网站首页 >> 知识专区
动态内存管理
文章来源:CSDN 沙漠下的胡杨  上传时间:2022-4-22  浏览量:514

本文链接:https://blog.csdn.net/m0_64770095/article/details/124312211

 什么是动态内存呢?

malloc使用

calloc

realloc

C程序地址空间

为什么要有动态内存开辟呢?

访问内存出错

指针合法性问题

内存越界

 内存泄漏

free多大空间呢?

free释放是在干嘛?

下期预告:



 什么是动态内存呢?

动态内存就是用malloc,calloc,realloc和free这些动态内存函数来进行向堆区申请空间,来交给程序员进行管理使用,这就动态内存管理。

malloc使用

malloc是申请一块空间,需要自己手动进行初始化,并且手动free和置空

calloc

calloc是开辟空间num个sizeof(类型)并初始化为0。


realloc

realloc有两种情况:

1.当源空间为0,即传入NULL时,和malloc作用一样。


2.如果做扩容空间时,即传入的指针有效时,又两种分为两种情况

         2.1.如果原空间后面空间足够,那么直接在原空间后面直接开辟,返回原空间的最低地址。(即返回值和传入值相同)


         2.2.如果原空间后面空间不够开辟的话,那么函数就会在堆区上,找一块能符合用户所需要的空间大小的空间,然后把原空间数据拷贝到函数开辟的空间上,然后把原空间释放,返回重新开辟的空间的最低的地址。

这个情况一般很少出现,所以不在举例子啦。

C程序地址空间

首先我们要明白堆区在C程序地址空间的那个地方呢?或者说C程序地址空间是什么呢?

我们今天我们主要聊下堆区。

为什么要有动态内存开辟呢?

首先我们知道平常申请空间可以直接在栈区上申请,那么为什么要有动态内存开辟呢?

举个例子:

我们要存放一些数字,这些数字可能很多,可能很少,这时我们该如何在栈区申请空间呢?

本着要全部存下的理念,我们要开辟空间大一点,但是栈区空间有限,稍微大点即形成栈溢出啦,这也就是为什么要有堆区的原因。

访问内存出错

比如定义一个结构体,其中结构体成员是动态开辟的,如果没有初始化就使用,那么就会导致访问内存出错。

				
  1. struct stu
  2. {
  3. char* p;
  4. int age;
  5. }s1;
  6. int main()
  7. {
  8. strcpy(s1.p, "胡杨树下");
  9. s1.age = 18;
  10. return 0;
  11. }

这里的  s1.p  虽然是变量,但是没有相对性的空间,所以就会导致访问内存出错。

上面说啦,应该给 s.p开辟空间,下面就看看怎么开辟吧,下面的开辟是没问题的。

				
  1. struct stu
  2. {
  3. char* p;
  4. int age;
  5. }s1;
  6. void Show(char *name)
  7. {
  8. printf("%s\n", name);
  9. }
  10. int main()
  11. {
  12. struct stu s1 = { NULL, 0 };
  13. s1.p = (char *)malloc(sizeof(char)* 30);
  14. strcpy(s1.p, "胡杨树下");
  15. Show(s1.p);
  16. free(s1.p);
  17. s1.p = NULL;
  18. return 0;
  19. }

指针合法性问题

首先,什么 "合法" 的指针呢?

一般来说,就是传递的指针是能正常使用的。

如果一个指针它是有指向的(野指针也是有指向的,只不过不知道指向哪里),那么我们没办法判断 "合法" 性。所以我们要求指针如果没有直接被使用,那么就应该赋值为NULL,这样我们验证 ”合法“ 性的问题时,就变成了对指针判断是否为NULL。

对上面代码改进下就会变为以下的代码:

				
  1. struct stu
  2. {
  3. char* p;
  4. int age;
  5. }s1;
  6. void Show(char *name)
  7. {
  8. if (name == NULL)
  9. {
  10. exit(-1);
  11. }
  12. printf("%s\n", name);
  13. }
  14. int main()
  15. {
  16. struct stu s1 = { NULL, 0 };
  17. s1.p = (char *)malloc(sizeof(char)* 30);
  18. if (s1.p == NULL)
  19. {
  20. exit(-1);
  21. }
  22. strcpy(s1.p, "胡杨树下");
  23. Show(s1.p);
  24. free(s1.p);
  25. s1.p = NULL;
  26. return 0;
  27. }

这里经过判断指针是否为NULL,这样就避免空指针的情况。也可使用 assert(宏)进行断言,引用头文件 "assert.h",但是这种宏只能在调试版本使用,不能用于发布版本。

内存越界

相信大家都听过内存越界这个话题,那么指针越界一定会报错吗?

指针的越界有时候时不会进行报错的,比如:

 或者malloc之后没有free也是有概率不报错的。

但是不free会发生更严重的情况,叫内存泄漏。 

 内存泄漏

内存泄漏简单来说就是,程序只申请内存,不释放不free。

那么如果没有程序,或者程序退出啦,那么还有内存泄漏问题吗?

如果程序退出啦,那么操作系统会强制收回申请的内存。

内存泄漏最更害怕的是一些永远不会主动退出的程序,那么就很恐怖的事,一个进程,只申请内存,不释放,那么就没有内存可用啦。

free多大空间呢?

我们只知道free的起始地址,那么释放多大呢?

 我们看下,free的大小远远比释放的空间要大,所以就可以说,我malloc的大小要比我们要申请要大

因为malloc要申请的空间要有多余的空间来管理申请的空间,所以要比我们正常申请的要大,所以如果我们malloc要越界的话不一定会报错。

free释放是在干嘛?

free之后我们一般要把指针置空,为什么呢?不置空还会指向原空间吗?

 我们能看出空间的指向没变,也就是说指向没变,那么变的是什么呢

变的是p和堆区申请的关系,所以free就是改变的关系,free本质就是改变关系,也就是说p还指向堆区申请的空间,所以我们应该把这种关系断掉,就把p置为NULL。

就像你谈女朋友时,都分手啦,就不该留下联系方式啦,所以就该把联系方式断啦。

21

2021-04

Java程序员都要懂得知识点:原始数据类型

Java程序员都要懂得知识点:原始数据类型

29

2021-06

python自制一款职位分析器,一键生成岗位分析报告

python自制一款职位分析器,一键生成岗位分析报告

15

2021-07

MySql知识体系总结(SQL优化篇)

MySql知识体系总结(SQL优化篇)

18

2022-02

Redis6-雪崩、击穿、穿透、分布式锁

Redis6-雪崩、击穿、穿透、分布式锁

14

2022-01

win10 如何做到 C盘 的绝对干净,所有软件都安装到D盘,C盘只用来存操作系统。

win10 如何做到 C盘 的绝对干净,所有软件都安装到D盘,C盘只用来存操作系统。

18

2022-02

静态路由简介及配置

静态路由简介及配置

26

2021-04

三步法助你快速定位网站性能问题

三步法助你快速定位网站性能问题

28

2021-07

有了这7款浏览器插件,浏览器居然“活了”?!

有了这7款浏览器插件,浏览器居然“活了”?!
返回顶部
客服电话
0871-64605728
用微信扫一扫关注我们
请各公司推销人员注意:我单位拒绝任何方式、任何形式的电话推销,请勿拔打我单位客服热线进行电话推销,谢谢合作!
公司名称:云南昂略科技有限公司
联系地址:云南省昆明市官渡区永平路188号鑫都韵城写字楼6栋1004号
联系电话:0871-64605728、传真号码:0871-64605728
电子邮箱:19701580@qq.com
关键词:知识专区:动态内存管理,云南昂略科技有限公司,云南移动执法平台建设,云南智慧安防调度系统,云南头戴式安全终端,昂略科技
云南网站建设,云南网页设计,昆明网站建设,昆明网页设计  网站管理
【版权声明】本站部分内容由互联网用户自行发布,著作权或版权归原作者所有。如果侵犯到您的权益请发邮件致info@ynjwz.com,我们会第一时间进行删除并表示歉意。