C语言动态内存管理、内存泄漏

为什么需要动态分配内存?

普通的内存开辟方法自能开辟固定的空间大小,一旦开辟空间的大小就不能改变。这种情况是经常遇到的:需要开辟的空间大小在程序运行时才能确定,这时候提前开辟多大的空间都感觉不是很合适,小了怕不够,大了又担心空间浪费,这时候动态开辟内存就能很好的解决问题。

动态内存管理的相关函数

动态内存管理的相关函数都包含在stdlib.h和malloc.h两个头文件中,使用时引用其中一个即可。

malloc(开辟空间)
void* mallloc(size_t size)

可以看出:malloc向内存申请一块连续可用的空间,并返回指向这块空间的指针。
1.如果开辟成功,则返回一个指向开辟好的空间的指针。
2.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。

int* p = NULL;
p = (int*)malloc(num * sizeof(int))
if(p != NULL){  //检查malloc的返回值
	//使用空间
}	

3.malloc的返回类型是void*,所以malloc函数开辟空间时并不知道开辟空间的类型。
4.如果参数size为0,malloc的行为是未定义的,取决于编译器(也就是说布置到函数会干什么,不同编译器有不同的做法)

free(释放空间)
void free(void* ptr);

1.如果参数ptr指向的空间不是动态开辟的,则free函数的行为是未定义的。
2.如果参数ptr是NULL空指针,则free函数不做任何操作。

calloc(开辟并初始化空间)
void* calloc(size_t num, size_t size)

calloc与malloc的唯一区别在于calloc在返回指向所开辟空间前会把开辟的所有字节初始化为0 。calloc同样需要检查返回的指针是否为空。

realloc(对开辟的动态空间扩容)
void* realloc(void* ptr, size_t size)

1.ptr是要调整的动态开辟的内存地址。
2.size为调整后的空间大小。
relloc函数的实现值得注意:
1.第一种:待扩展的空间后面有足够的空间以供扩展
2.第二种:待扩展的空间后面有没有足够的空间以供扩展,函数会自动寻找一块足够大的空间重新开辟整个空间,而不是扩展。如果是第二种情况,容易让编程者出现一个错误:relloc扩容后空间对应的指针已经不是原来的指针。对旧的指针进行操作不会对目标空间造成任何改变。

动态管理内存容易发生的错误

1.不检查malloc、calloc、realloc函数的返回值是否为NULL。
2.访问动态开辟的内存之外的空间。

int i = 0;
int* p;
p = malloc(sizeof(int) * 10);//这里动态开辟了可以容纳10个整型元素的空间
for (i = 0; i <= 10; i++);//0~10有11个数,访问到第11个数的时候会发生越界访问
{
	p[i] = i;
}

3.向free函数传递一个非动态内存管理函数返回的指针。
4.在动态内存释放后再访问它。

什么是内存泄漏?

内存泄漏:当开辟的动态内存不再需要使用时,他应该被释放,这样这块空间以后才能重新分配使用。而如果只开辟而不释放就会引起内存泄漏。通俗点说,如果不使用free释放动态分配的内存,那么那块内存将不再能被使用。
内存泄漏很难被发现,因为少量的内存泄漏不会造成很大的影响,系统也不会报错。持续的内存泄漏会导致内存一点点的被占用,足够长的时间后,可以使用的内存越来越少,最后系统或者服务器便会因没有内存使用而崩溃。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值