【C语言】realloc函数

前言:在C/C++的学习过程当中一定一定要多刷题,牛客网作为国内内容超级丰富的IT题库,尤其是它的C、C++,有从入门到大厂真题,而且大部分的考试题目也是从中抽取,还有很多面经,推荐大家去牛客网进行刷题练习,点击链接牛客网刷题入口


前言

有时我们觉得我们用malloc,calloc函数申请的动态内存空间太大了,有时觉得申请的空间太小了,为了合理使用内存,我们要对内存的大小做灵活的调整,那么realloc函数就可以做到控制动态内存开辟的大小。

一、认识了解realloc函数

1.realloc函数的原型:

void* realloc(void* memblock, size_t size)

头文件:stdlib.h
realloc函数返回的是void*类型的指针,指向在堆区重新开辟的内存块的起始地址,memblock是先前开辟的内存块的指针(也就是malloc或calloc之前申请的那块内存空间,即需要调整大小的内存空间),size_t size指的是New size in bytes,新的字节数,注意不是增加的字节数,而是新开辟的那块内存空间的字节数,返回值为调整之后的内存的起始地址。

二、使用realloc函数

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
	int* p=(int*)malloc(20);
	int i;
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		for (i = 0; i < 5; i++)
		{
			*(p + i) = i;
		}
		for (i = 0; i < 5; i++)
		{
			printf("%d ", *(p + i));
		}
	}
	//假设这里20个字节的空间已经不能满足我们使用了
	//我们需要40个字节的空间
	//这里就可以使用realloc调整动态开辟的内存
	int* ptr = (int*)realloc(p, 40);
	//开辟成功
	if (ptr != NULL)
	{
		p = ptr;
		for (i = 5; i < 10; i++)
		{
			*(p + i) = i;
		}
		for (i = 5; i < 10; i++)
		{
			printf("%d ", *(p + i));
		}
	}

	//考虑开辟失败的情况
	//若调整开辟40个字节失败,我们不能让原有的20个字节的空间的数据丢失
	//所以我们至少要返回原动态内存的起始地址,打印0 12 3 4
	//注意用完之后把动态内存释放
	free(p);
	p = NULL;
	
	
}

解析

1.如果p指向的空间之后有足够的空间可以追加,则直接追加,返回的是p原来的起始地址。
2.如果p指向的空间之后没有足够的空间可以追加,则realloc函数会重新找一个新的内存区域,重新开辟一块40个字节的动态内存空间,并且把原来内存空间的数据拷贝回来,释放旧的内存空间还给操作系统,最后返回新开辟的内存空间的起始地址。
3.我们需要用一个新的指针变量来接收realloc的返回值。
4.同时我们要考虑调整内存大小失败的情况,如果开辟失败,我们至少不能让原内存数据失效,我们也要释放原内存数据,并把指针置为空。
5.开辟成功,也不用担心原来的内存有没有浪费,因为realloc函数会把原来的内存空间拷贝回来,再将其内存释放。注意如果ptr!=NULL p=ptr;这个p指针已经被赋为ptr了(就不用考虑原内存空间的指针有没有被置为空指针),所以新空间不再使用时,也要释放内存,并把指针置为空。

6.realloc函数也可以具有与malloc函数相同的功能

	int* p = (int*)realloc(NULL, 20);

1)关于缩容的问题

如果我们realloc的新的内存块的大小<比之前动态内存malloc的大小,可不可以做到缩容来节省空间呢?
它有可能会原地缩容,也有可能会异地缩容。但我们一般不考虑缩容的问题,因为如果系统是异地缩容,它需要找一块空间,把原数据考虑过来,然后再把原空间释放,这样会有性能,时间上的代价。而且如果我们之后又要插入数据,那我们又要进行扩容。
总结一下来说:
缩容:以时间换空间
不缩容:以空间换时间

  • 109
    点赞
  • 462
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
05-24
`realloc` 函数是 C 语言标准库中的一种内存管理函数,用于修改已经分配的内存块的大小。其原型为: ```c void *realloc(void *ptr, size_t size); ``` 参数 `ptr` 是之前通过 `malloc`、`calloc` 或 `realloc` 分配的内存块的指针,参数 `size` 是需要重新分配的内存块的大小。如果成功,`realloc` 函数返回指向重新分配后的内存块的指针。如果失败,`realloc` 函数返回 `NULL`。 `realloc` 函数会尝试扩大或缩小内存块的大小,具体操作如下: 1. 如果 `ptr` 为 `NULL`,则等同于调用 `malloc(size)`,即分配 `size` 字节的内存块并返回指向该块内存的指针。 2. 如果 `size` 为 `0`,则等同于调用 `free(ptr)`,即释放 `ptr` 所指向的内存块,并返回 `NULL`。 3. 如果 `ptr` 不为 `NULL`,且 `size` 不为 `0`,则会尝试重新分配 `ptr` 所指向的内存块。 1. 如果重新分配后的内存块与原内存块的大小相同或更大,则直接返回 `ptr`。 2. 如果重新分配后的内存块比原内存块更小,则会截取原内存块中前面的一部分作为新的内存块,并将余下部分仍留在原内存块中。返回指向新的内存块的指针。 3. 如果重新分配后的内存块比原内存块更大,则会尝试扩大原内存块,如果原内存块所在的连续空闲内存块足够大,则直接扩大原内存块。否则,会重新分配一块更大的内存块,并将原内存块中的内容拷贝到新的内存块中。返回指向新的内存块的指针。 需要注意的是,`realloc` 函数可能会改变原先内存块的地址,因此必须将返回的指针重新赋值给原指针变量,如下面的示例所示: ```c int *p = malloc(10 * sizeof(int)); //分配 10 个 int 类型大小的内存块 p = realloc(p, 20 * sizeof(int)); //重新分配内存块大小为 20 个 int 类型 if (p == NULL) { //重新分配失败,处理错误 } //重新分配成功,使用 p 指向的内存块 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_麦子熟了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值