详解动态内存分配函数malloc、calloc、realloc、free的区别
动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
在扩容过程中,我们需要注意以下两个问题:如果增容空间过大而数据元素很少,就会导致内存空间浪费;
如果增容空间不足而数据元素较多,就会导致内存溢出现象。
全局变量被编译器编译时,开始分配其内存单元,生命周期持续到程序运行结束;局部变量比如函数参数,当程序被调用时为参数分配内存单元,函数调用结束生命周期也结束,所占用的内存单元被释放;那么除此之外还有一种情况,就是生命周期由用户自己决定,需要多少内存就开辟多少内存,用完了的时候释放就可以了,并且这些内存一般是用来存储一些临时数据,所以称为内存的动态分配,而这个存储区成为堆(heap)。所以将C语言中常用的存储区分类:
怎样建立内存的动态分配
系统提供的库函数:
注意:这些函数定义在库函数stdlib.h中,在使用时需要调用其头文件。
动态内存分配函数malloc
函数原型:void *malloc(unsigned int size);
函数特点:函数为无符号指针函数,返回值是不指向任何数据类型的此函数所开辟的内存空间的首地址;参数为无符号整型,因为要开辟的内存空间数不会是负值;如果开辟空间失败(内存不足或其他情况),函数返回值为NULL;此段内存空间中的值为任意值,也就是没有进行初始化,memset函数可以完成对这个空间的初始化;
运行结果:(这个地址是随机的,每次运行结果并不相同)
图像表示"p = malloc(100)":
相关视频推荐
【C++开发】庞杂的内存问题,如何理出自己的思路出来,让你开发与面试双丰收
5种内存泄漏检测方式,让你重新理解C++内存管理
200行代码实现slab,开启内存池的内存管理(准备linux环境)C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
需要C/C++ Linux服务器架构师学习资料加qun579733396(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
动态内存分配并清零函数calloc
函数原型:void *calloc(unsigned int n , unsigned int size);
函数特点:函数同样为空类型指针类型,返回的地址同样为所开辟空间的首地址,如果开辟失败,则返回NULL;开辟的是一个数组空间,此数组一共n个元素,每个元素的存储字节数为size;除了开辟空间之外,此函数还为每个元素赋初值为0;函数calloc() 会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零.
举例:
运行结果:(这个地址是随机的,每次运行结果并不相同)
图片解释“p = calloc(4,100)”:
动态内存调整函数realloc
函数原型:void *realloc(void *p,unsigned int size)函数特点:函数返回值为指针,如果操作失败(内存不足或其他)返回为NULL;函数用来重新分配由malloc和calloc函数所开辟的首地址为p内存空间,修改其大小为size;重新分配后,p的值可能会发生改变;此函数是堆中开辟的内存;
realloc是从堆上分配内存的.当扩大一块内存空间时,realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;如果数据后面的字节不够,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。这句话传递的一个重要的信息就是数据可能被移动。
realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。realloc并不保证调整后的内存空间和原来的内存空间保持同一内存地址.相反,realloc返回的指针很可能指向一个新的地址。
举例:
运行结果:(这个地址是随机的,每次运行结果并不相同)
图片解释“realloc(p,120)”:
但是realloc函数不仅可以增加拓展内存空间,还可以缩短内存空间;
例如:realloc(p,80)代表:
注意:
那么,这些内存的开辟干什么用哪?
用来存临时数据, 而且是一般存储的数据往往都是有一定量的,但是这里有个问题:分配的临时存储空间内并没有数据类型,例如malloc开辟的空间,就只是一个由若干个字节组成的内存空间块,如何像数组一样去存储数据,并按照地址去访问它们?解决这个问题的办法是强制类型转换;并且有一点要说明的是,在C99之前,malloc和calloc函数的数据类型是字符指针型(char *)的,但即使是这样,这些内存空间并不一定是用来存字符的。
举例说明:
图片解释:“p = (int ) malloc(5sizeof(int)); ”
显然,所开辟的空间被转换成了数组一样的内存空间,并存储了数据,各个小存储区可以利用指针的算术运算存取。
动态内存释放函数free
函数原型:void free(void *p);函数特点:此函数用来释放指针p所指针的动态内存空间;一般和malloc函数搭配使用;一般free函数释放的是最近开辟的一个内存空间;
当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏。一部分的内存没有被使用,但是由于没有free,因此系统认为这部分内存还在使用,造成不断的向系统申请内存,使得系统可用内存不断减少。但是内存泄漏仅仅指程序在运行时,程序退出时,OS将回收所有的资源。因此,适当的重起一下程序,有时候还是有点作用.
举例说明:
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/93801.html