【C语言】动态内存管理

目录

为什么会存在动态内存管理??

动态内存函数的介绍

malloc 和 free

malloc - 开辟

free - 释放

如何正确释放

calloc - 开辟

realloc - 扩容

小结


为什么会存在动态内存管理??

    int arr[10] = { 0 };

    这样创建数组不可以吗???

答案是可以,但有缺陷。

创建数组时需要声明数组容量的大小,表明我们已经指定了数组只能装下10个int类型的元素,在编译时就已经确定了,而有时候数组容量的大小需要在运行程序时才能知道,这样我们就考虑一下动态开辟空间吧。

动态内存函数的介绍

在堆区开辟空间

malloc 和 free

malloc - 开辟

void *malloc( size_t size );

头文件:<stdlib.h> and <malloc.h>

返回值为void*型,所以需要使用者根据情况进行转换;

size表示需要开辟空间的大小,单位为字节

malloc回想内存申请一块连续可用的内存空间,开辟内存空间成功会返回一个指向该空间的指针,如果没有开辟好则会返回NULL

因此我们要判断返回值是否为NULL,以避免发生错误

若size为0,这是标准未定义的,取决于编译器。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int* arr = NULL;
	arr = (int*)malloc(20);
	if (arr == NULL)//判断是否开辟成功
	{
		return 1;
	}
	int* ret = arr;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*arr = i;
		arr++;
	}
	for (i = 0; i < 5; i++)
	{
		printf("%d ", ret[i]);//打印 0 1 2 3 4
	}
	free(ret);
	ret = NULL;//释放内存空间
	return 0;
}

正所谓欠债还钱,天经地义;我给你开辟空间供你使用,如果你不给我还回来,那么我就要占用你的内存,发生内存泄漏。

free - 释放

专门用来释放动态内存空间

void free( void *memblock );

头文件:<stdlib.h> and <malloc.h>

memblock 代表指向该空间的指针

malloc常与free相配对。

在开辟动态内存空间后,要用free释放内存空间,但有几点注意事项:

①传入的指针指向的空间一定是完整的动态内存空间,不能指向一部分空间

例如:

注意:我开辟了20个字节,但是我指初始化了16个字节的空间

 ②不能多次释放同一块内存空间

③只能释放动态开辟的空间

	int a = 4;
	int* pa = &a;
	free(pa);
	pa = NULL;//错误代码  非动态开辟

 ④传入空指针 则什么也不做

free(NULL);//传入空指针 则什么也不做

⑤不要忘记释放,会发生内存泄漏

如何正确释放

我称之为释放内存两部曲

	int* arr = NULL;
	arr = (int*)malloc(20);
	if (arr == NULL)//判断是否开辟成功
	{
		return 1;
	}
	int* ret = arr;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*arr = i;
		arr++;
	}
	for (i = 0; i < 5; i++)
	{
		printf("%d ", ret[i]);//打印 0 1 2 3 4
	}

//两部曲
	free(ret);
	ret = NULL;//释放内存空间

最后一步置为空指针是否有必要呢???

答案是很有必要。

 因此我们将其置为空指针,防止后续出错;不为空时再进行使用。

calloc - 开辟

void *calloc( size_t num, size_t size );

该函数为:为num个大小为size的元素开辟一块空间,并将其初始化为0,开辟成功则返回指向该空间的指针,否则返回NULL,所以我们依然要对返回值进行判断,且开辟后记得释放空间。

该函数与malloc的区别只在于calloc会将开辟的空间中的每个字节初始化为0。

realloc - 扩容

当开辟的内存空间不够了怎么办呢,空间不够,realloc来“凑”

void *realloc( void *memblock, size_t size );

memblock:指向先前分配的内存块的指针

size:所需字节数(若比之前所开辟的空间的字节数大则为扩容,反之则为缩小)

返回值为指向新空间的指针,扩容失败返回空指针

扩容的两种情况:

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

 

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

 扩容之后返回的指针我建议大家用另一个临时指针变量来接收,当确定不为空时再赋给本应掌管这片空间的主人。

解释:

 

不用另一个指针来接收:假如realloc扩容失败,返回空指针赋给arr,那么此时arr被置为空,本来arr原来还掌管着自己的一片天地,现在可好,一无所有了,找不到原来空间的地址了,你说冤枉不冤枉,所以我们需要一个“保镖”替我们接收,检查“无毒无害(不为空指针)”后 ,再给我们的主人,这才叫万全之策,出了事儿也不脏自己的手。

小结

不管是malloc、calloc还是realloc的返回值都要进行判断,且realloc要用另一个指针来接收,确认不为空 再赋给先前开辟空间返回的指针

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值