动态内存管理

2023-12-13 23:16:32

目录

动态内存函数?

malloc函数

free函数

calloc函数

realloc函数

?几道经典笔试题

题1

?题2

题3

?编辑

题4

柔性数组

柔性数组的特点

柔性数组的优点?


动态内存函数?

malloc函数

如上图,malloc函数被用来申请10个整形大小的空间,malloc函数的返回类型是void*,因为malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来定义。因此我们需要对他进行强转,然后赋给p即可使用。

malloc函数的返回值: 如果申请的空间开辟成功,则返回一个指向开辟空间的指针。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如果开辟失败,则放回NULL指针,就不能使用了。因此我们需要对返回? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?值进行检查。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如果参数为0,malloc行为标准未定义,取决于编译器。

我们会习惯性的对malloc的返回值进行检查,如上图,如果返回了NULL,则打印错误的信息。

free函数

free函数是专门用来做动态内存的释放和回收的。

malloc开辟的空间有两个释放方式:

  1. free释放——主动
  2. 程序退出后,malloc申请的空间,也会被系统回收——被动

正常情况下,我们要主动释放。

free函数没有返回值,他的参数就是开辟空间的地址。

如上图,我们释放时,只是释放了开辟的空间,但p还是指向那个地址,因此,我们会在free之后将该指针变为空指针,否则该指针就是野指针,野指针是危险的。

  • 如果free参数指向的空间不是动态开辟的,则free函数的行为是未定义的。
  • 如果参数是空指针时,则函数什么也不做。

malloc和free都需要引用头文件stdlib.h。

calloc函数

calloc函数和malloc函数返回值类型都一样void*,calloc的参数有两个,参数1指开辟空间的个数,参数2指开辟空间的类型的大小。

如上图,同样开辟10个整形大小的空间,二者的差别不大。除了参数的区别,calloc函数申请好空间后,会将空间初始化为0,但是malloc不初始化。?

realloc函数

  • realloc函数有两个参数,参数1是要调整的空间的地址。
  • 参数2是调整之后的大小。
  • 返回值是调整之后的内存起始地址。
  • 这个函数调整原内存空间的基础上,还会将原来内存中的数据移到新的空间。

realloc在调整内存空间存在两种情况:

假设初始已申请10个整形的空间,现需要调整为20个整形的空间。

  • 原有空间之后有足够的空间

  • 原有空间之后没有足够大的空间

如上图,因为后面没有足够大的空间,realloc函数会找一块新的,足够的空间,一次性开辟需要的空间。

  • 旧的空间中的数据,会拷贝到新的空间中。
  • 释放掉旧的空间。
  • realloc函数返回新的空间的地址。?

realloc也能做malloc能做的事,如果参数1是空指针,上方realloc函数的作用跟注释中malloc函数的作用一样。

?几道经典笔试题

题1

分析:str指向的空间仍为NULL,因为GetMemory后p会被销毁,程序对str(NULL)进行解引用操作,会使程序崩溃。但是malloc开辟的空间依旧存在,没有释放,会造成内存泄漏。

修改后的代码如下:

?题2

分析:p的地址返回给str,但返回时,该空间已经销毁了,即没有了该空间的使用权,str指向了p所指向的地址,但此时str是野指针。

题3

分析:缺少free,造成内存泄露。

题4

分析:free后,str指向的空间被释放了,但他依旧指向该地址。strcpy时,此时str为野指针,对野指针进行操作,非法访问内存。?

柔性数组

?结构体中最后一个元素允许是未知大小的数组,这就叫柔性数组成员。

柔性数组的特点

  • 结构体中的柔性数组成员前面必须至少有一个其他成员
  • sizeof返回这种结构大小不包括柔性数组的内存
  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

如上图,不包括柔性数组的内存。?

柔性数组的优点?

请看下面两组代码

组1:

?

?组2:

?

?分析组2:组2的结构体中有柔性数组成员,先是申请一块空间,后来空间不够,就realloc进行调整,并把调整后的地址传给先前的ps,开辟的空间是连续的。在释放时,只需要释放一次。

分析组1:组1先是malloc一块空间,然后在data中再malloc一块空间。空间不足时,再realloc调整,然后把新空间的地址传给data。malloc开辟的空间不是连续的。由于malloc了两次,在释放时也需要释放两次,即malloc几次,就要free几次,这样释放内存相较于组1,更为麻烦。如下图。

组2有两个优点:

  1. 方便内存释放:
  2. 有利于访问速度?

文章来源:https://blog.csdn.net/qinjh_/article/details/134904724
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。