关于动态内存分配以及常见的动态内存函数的介绍

在之前的学习中我们已经知道的内存开辟方式有:

int val = 20;	//在栈空间上开辟四个字节
char arr[10] = { 0 };	//在栈空间上开辟10个字节的连续空间

在上面这两种开辟空间的方式有两个特点:
1.空间开辟的大小是固定的.
2.数组在声明的时候,一定要指定数组的长度,它所需要的内存在编译时分配.
在我们的实际应用中,对于所需要的空间需求,往往不仅仅是上面两种情况!也就是说,有时候我们需要的空间大小在程序运行的时候才能知道,那像上面这正数组的编译时开辟空间的方式就不能满足了.这个时候就要用到我们的动态开辟内存了.
这也就是动态内存分配存在的原因.

关于动态能存的几个函数介绍

malloc和free
在C语言中提供了这样一个动态开辟内存的函数:

void* malloc(size_t size);
//开辟size字节的连续空间,并将首地址返回

这个malloc函数向内存申请一块连续可用的空间,并返回指向这块空间的指针.
在使用malloc函数动态开辟内存要要注意:
1.如果内存开辟成功,就返回一个指向开辟好空间的指针,一定要注意malloc函数的返回值是一个指向开辟好空间的指针!
2.如果内开辟失败,就会返回一个NULL指针,这也就意味着,malloc函数的返回值一定要做检查.
3.malloc函数的返回值是void* ,所以malloc函数并不知道开辟空间的类型,所以malloc函数具体在使用的时候由使用者自己来决定.
4.如果malloc函数的参数size为0,那么malloc函数的行为标准是未定义的,具体行为取决于编译器.

来看一个动态内存开辟的例子.

#include <stdio.h>
#include <stdlib.h>
int main(){
	int* p = NULL;
	p = (int*)malloc(sizeof(int));
	*p = 8;
	printf("%d\n", *p);
	system("pause");
	return 0;
}

先创建一个空指针,让这个指针指向动态开辟的4字节空间,然后给其赋值.这样也就完成一个简单动态内存的开辟.但是要注意的是,这样使用malloc函数会造成内存泄漏,malloc函数动态开辟的空间在使用完之后一定要记得释放,这也就用到了free函数.

void* free(void* ptr);

切记,开辟谁,释放谁.
如果参数ptr指向的空间不是动态开辟的,那么free函数的行为是未定义的.
如果参数ptr指向NULL指针,free函数什么都不做.
malloc函数和free函数都声明在stdlib.h头文件中.

所以对上述代码稍作修改

#include <stdio.h>
#include <stdlib.h>
int main(){
	int* p = NULL;
	p = (int*)malloc(sizeof(int));
	*p = 8;
	printf("%d\n", *p);
	free(p);
	p = NULL;
	system("pause");
	return 0;
}

这样才是malloc函数使用正确方法.
释放掉动态开辟的内存之后我们再次把p置为空,是为了防止p变成野指针(动态开辟的内存释放后,p仍指向这块内存空间,所以释放之后记得将p置为空)

calloc函数
除了malloc函数之外,C语言还提供了一个函数叫calloc,而calloc函数同样也用来动态开辟内存.

void* calloc(size_t num, size_t size);

calloc函数的功能是将num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0.
calloc函数与malloc函数的区别只在于calloc函数会在返回地址之前把申请的空间的每个字节初始化为全0.举例来说:

#include <stdio.h>
#include <stdlib.h>
int main(){
	int* p = calloc(10, sizeof(int));
	if (p != NULL){
		//说明空间开辟成功
		//使用动态开辟的空间
	}
	free(p);
	p = NULL;
	system("pause");
	return 0;
}

所以当我们对申请的内存空间的内容要求初始化的时候,我们就可以很方便的用calloc函数来完成任务.

realloc函数
realloc函数的出现让动态内存管理更加灵活.
有时候我们在动态开辟内存的时候会发现,过去申请的空间太小了,或者有时候我们又会觉得申请的空间过大了,为了合理地动态开辟内存,就一定要对内存的大小做灵活的调整.而realloc函数就可以做到对动态开辟内存大小的调整.

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

ptr是要调整的内存地址.
size是调整之后的新大小.
注意realloc函数是将当前ptr所指向的空间扩大或缩小到size个字节.
返回值是调整之后内存的起始位置.同样开辟失败返回空.
这个函数在调整内存空间大小的基础上,还会降原来内存中的数据移动到新的空间.
realloc函数在调整内存空间时存在两种情况:
1.原有空间之后有足够大的空间
2.原有空间之后没有足够大的空间.
是情况1的时候,要扩展内存就直接在原有内存之后直接追加空间,原来空间的数据并不会发生变化.
是情况2的时候,原有空间之后没有足够多的空间时,会在堆空间上另找一个合适大小的连续空间来使用.这样的话realloc函数返回的是一个新的内存地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值