C语言学习————堆内存管理

C语言不包含管理堆内存的语句,而是通过标准库中的函数如malloc,calloc,free和realloc进行内存动态管理。malloc用于申请内存,calloc用于申请并初始化为0的内存块,free用于释放内存,realloc调整内存块大小。内存碎片和内存泄漏是动态内存管理中的问题,需要合理分配和释放内存来避免。对于服务器端程序,内存问题可能导致系统性能下降甚至崩溃。
摘要由CSDN通过智能技术生成

C语言中没有管理堆内存的语句,C标准库中提供一套管理堆内存的函数,这些函数底层封装了各操作系统的堆内存管理接口,所以可以跨平台使用,这些函数声明在 stdlib.h 头文件中。

malloc函数:

void *malloc(size_t size);
功能:向malloc申请位size字节的堆内存块

size为申请的字节数

例:int main(int argc,const char* argv[])
{
    int* p = malloc(4);
    printf("请输入一个整数:");
    scanf("%d",p);
    printf("%d\n",*p);  
}

注:

1、使用malloc申请到的内存块,里面的内容是不确定的,malloc不会帮我们初始化,可以使用bzero,memset函数进行初始化。

2、如果size等于0,返回NULL或唯一个的地址,并且该地址可以通过free释放而不出错,但不能使用它指向的内存。

calloc函数:

size:数组元素的字节数
void *calloc(size_t nmemb, size_t size);
功能:申请nmemb个size个字节的内存块,专门用于申请数组型的内存块。
nmemb:数组的长度
size:数组元素的字节数

注意:

1.使用calloc申请的内存块,所有字节会被初始化0。

2、calloc所申请也是一块连续的内存块,所以nmemb和size的参数位置可以调换,就相当于calloc内部调用了malloc函数,只是比malloc多了初始化步骤,而且比malloc的可读性更高。

3、malloc比calloc申请内存的速度快,或者使用malloc+bzero配合。.

free函数:

void free(void *ptr);
功能:释放堆内存 
ptr:要释放的内存块的首地址,它必须是malloc、calloc函数的返回值

1、free释放的是使用权,只破坏内存块的一部分内存,大部分数据还在,这样设计的原因是释放速度比较快,就像在硬盘上删除文件一样,只是把存储文件那片区域的使用释放旧,数据还存储在磁盘上,这也是我们能进行数据恢复的原因。(只是破坏首地址)

2、free的参数可以是空指针,不会出现错误,也不会执行任何操作,这也是空指针比野指针安全的原因。

3、如果内存被重复释放则会出现"double free or corruption (fasttop)",程序会异常停止,所以在第一次释放内存后,要把与堆内存配合的指针及时的赋值为空,防止重复释放产生的错误。

realloc函数:

void *realloc(void *ptr, size_t size);
功能1:把已有的堆内存块调小
    ptr是malloc、calloc、realloc的返回值,也就已有堆内存块首地址
    size < oldsize 
    此时不需要关心realloc的返回值

注意:

虽然realloc具有释放和申请堆内存的功能,但我们一般不使用,而是直接使用malloc和free,主要使用的是realloc的调整内存块大小的功能。

内存碎片:

什么是内存碎片:

已经释放了使用的权的内存,但无法被malloc再次分配出去,这种内存叫内存碎片。

内存碎片产生的原因:

内存和释放、分配时间、大小不协调导致的。

一块内存碎片,只是短时间内是碎片,过一段时间它可能就不是碎片了,所以内存碎片不是绝对的。

如何减少内存碎片:

前提:内存碎片只能尽量减少,无法杜绝。

1、尽量使用栈内存(要了解栈内存的特性,要知道栈内存的使用上限,ulimit -s 、ulimit -s <size>)。

2、尽量分配大块内存自己管理。

内存泄漏:

什么是内存泄漏:

内存已经不再使用,但无法被释放的内存叫内存泄漏。

但这不是最严重的,严重的是反复的内存泄漏,例如:一个函数执行需要分配一块堆内存,等它执行完毕后堆内存没有被释放,等再次调用这个函数时,它又重新分配堆内存,又没有释放,反复这样会导致可用的内存越来越少,系统、程序会变得越来越慢、卡、死机。

产生内存泄漏的原因:

1、只写的内存分配语句,而忘记写内存释放语句,可能是粗心大意,也可能是以为别人会释放。

2、写了内存释放语句,但由于执行流程、执行条件设计有问题,导致释放语句没有执行。

3、与堆内存配合的指针被破坏,改变了指向,导致free语句执行无效。

如何减少内存泄漏:

1、按规则分配、释放内存:

自用:谁申请谁释放,分配语句和释放语句成对出现。

共用:谁知道该释放谁释放,项目组中负责分配和负责释放的人要进行对接。

2、封装malloc和free函数,记录每一次的分配和释放的内存块地址,通过对比记录,就可以发现是否有内存泄漏。

内存泄漏和内存碎片的危害:

前提:当程序结束时,操作系统会把分配它的所有资源全部回收(包括系统分配给程序的堆内存),所以当程序结束时,内存碎片和内存泄漏就会消失,这也是为什么软件、系统重启能解决很多问题。

注意:服务器端的程序一般需要7*24小时运行,不能随意结束。

客户端的程序可以随意的关闭、重启系统和软件,所以即使发生内存碎片和内存泄漏,也问题不大,但如果是服务端的程序,即使只有少量的内存泄漏和内存碎片,长年累月下来也会导致系统可用的内存越来越少,系统、程序会变得越来越慢、卡、死机。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值