初始动态内存

动态内存

我们已经懂得了开辟内存的方法:

int a = 10;
char b[10] = {0};

创建一个整型变量a,占用4个字节,一个有10个元素的char类型的数组b,占用连续的10个字节,但是以上开辟都是静态的,是固定死的,但有些时候我们只有再运行时才能知道需要多大的空间,就比如我们写一个通讯录,如果静态的开辟空间的话,假设我们开辟了一块可以存储100个联系人信息的空间,但是我们只有5个人的信息需要存储,这时就浪费了95个空间,而如果我们有120个人的信息需要存储,这时空间就会不足,所以这时候就会不灵活,到时空间的利用效率不高,这时候只能尝试动态开辟了。


动态内存函数

下面给大家介绍几个常用的动态内存函数:

malloc

开辟一块由你指定大小的空间,单位是字节,并返回一个void*的指针,需要注意的是malloc开辟空间可能存在失败,开辟空间失败会返回NULL。

库中的声明:

void *malloc( size_t size );

  • size:表示要开辟的空间的大小,单位是字节

头文件:

#include <stdlib.h>

可以看到malloc返回的指针类型是一个void* 的指针,使用时应把malloc返回的指针强制转换为我们所需要的类型的指针,就好比如:

int main()
{
	//开辟一块占用40个字节的空间,返回的指针强制转换为int*由ret接收
	int* ret = (int*)malloc(40);
	return 0;
}

//也可以这样写
int main()
{
	//开辟一块占用40个字节的空间,返回的指针强制转换为int*由ret接收
	int* ret = (int*)malloc(10 * sizeof(int));
	return 0;
}

前面我们也提到了,malloc开辟空间可能会失败,而失败会返回NULL,所以我们在使用malloc开辟空间时,最好先判断一下返回的是不是NULL,如果开辟空间失败而不加以判断就使用的话,那么对NULL的使用和访问就都是非法的,所以应该这样加以判断:

int main()
{
	int* a = NULL;
	int* ret = (int*)malloc(10 * sizeof(int));
	if(ret == NULL)
	{
		perror("malloc()");//头文件:<stdio.h> or <stdlib.h>
	}
	else
	{
		a = ret;
	}
	return 0;
}

在malloc开辟空间后,我们先把它的返回值存到ret里,然后判断ret是否为NULL,如果为NULL的话,就用perror这个函数输出错误信息,如果不为NULL的话,就把其赋值给a,a也就指向了这块动态开辟出来的空间。

下面是开辟空间失败的情况:

int main()
{
	int* ret = (int*)malloc(INT_MAX);//INT_MAX头文件:#include<limits.h>
	int* a = NULL;
	if (ret == NULL)
	{
		perror("malloc()");
	}
	else
	{
		a = ret;
	}
	return 0;
}

错误信息:

在这里插入图片描述
可以看到,在我们要开辟INT_MAX那么大一块空间的时候,开辟失败了,而从错误信息中也可以清楚的了解到,没有足够的空间可以开辟,所以开辟失败,返回了NULL。

calloc

calloc实现的功能和malloc99%是一致的,只不过calloc会将开辟的空间全部初始化为0,而malloc则不会初始化。

库中的声明:

void *calloc( size_t num, size_t size );

  • num:表示元素的个数
  • size:表示每个元素的大小,单位是字节

头文件:

#include <stdlib.h>

calloc的使用方法和malloc是一致的,开辟失败返回NULL也是一致的,所以在使用时最好也能判断一下calloc返回的是否是NULL,唯一不同的就是calloc会把每个字节都初始化为0。

如下所示:

calloc:
在这里插入图片描述

malloc:
在这里插入图片描述

realloc

reallo函数使得动态内存的管理更加灵活,realloc的作用是扩大或者缩小动态开辟出来的空间,对空间的大小做出合适的调整。

库中的声明:

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

  • memblock:指向动态开辟的内存块的指针
  • size:调整后的大小,单位是字节

头文件:

#include <stdlib.h>

realloc在调整内存空间时会存在两种情况:

  • memblock后面还有足够大的空间:

在这里插入图片描述

如果memblock后面还有足够的大小,足以放得下realloc调整后的空间的话,那么直接在原来的所占空间基础上接上要增加的空间即可。

  • memblock后面没有足够大的空间:
    在这里插入图片描述
    假设memblock后面没有足够的空间,那么realloc就会另行开辟一块足够的空间,然后把你原来空间的数据都拷贝下来,在成功开辟的情况下返回一个地址,这样看起来就是既调整了空间,数据又没有发生变化。

free

free是对动态开辟的空间的释放,如果动态开辟的空间你已经不使用了,那么就要使用free来进行回收,如果只是一味的动态申请空间而不去释放归还的话,就可能会导致内存泄漏,导致不可预估的结果。

库中的声明:

void free( void *memblock );

  • memblock:动态开辟空间的首地址

头文件:

#include <stdlib.h>

free使用注意事项:

  • 如果不是动态开辟出来的空间,不能使用free来进行释放,因为没必要,释放不是动态开辟出来的空间这种写法是错误的!
  • 如果memblock是NULL指针,那么free什么都不会做!
  • 释放指针所指向的动态开辟的空间之后,一定要记得把它的指向置为NULL,如果不置为NULL,虽然空间释放了,但它还是保存了这个空间的地址,这样不安全。

举例:

int main()
{
	//释放非动态开辟空间——error
	char* str = "Hello World";
	free(str);
	
	//释放的指针所指向为NULL——什么事都不会做
	int* arr = NULL;
	free(arr);

	//动态开辟出来的空间,一定要记得释放!!!
	int* ary = (int*)malloc(66);
	free(ary);
	ary = NULL;
	return 0;
}

结语

谢谢阅读,如果有哪里说的不对的地方,欢迎指出!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值