【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的大小,可不可以做到缩容来节省空间呢?
它有可能会原地缩容,也有可能会异地缩容。但我们一般不考虑缩容的问题,因为如果系统是异地缩容,它需要找一块空间,把原数据考虑过来,然后再把原空间释放,这样会有性能,时间上的代价。而且如果我们之后又要插入数据,那我们又要进行扩容。
总结一下来说:
缩容:以时间换空间
不缩容:以空间换时间
相关文章
- C语言字符串函数总结
- 【C语言入门教程】7.4 共用体
- 浅析C语言中strtol()函数与strtoul()函数的用法
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
- C语言变长数组data[0]【总结】
- C语言/C++基础之图解热力学模拟实验
- C语言/C++基础之小猪佩奇
- C语言 编写一个菜单函数(登录密码、水仙花数、闰年、素数)引发的思考
- linux系统调用函数(C语言):open,close函数和文件描述符
- ZZNUOJ_C语言1092:素数表(函数专题)(完整代码)
- 【C语言】详解 malloc 、calloc函数的区别
- 【C语言】详解线程回收函数 pthread_join
- 一起talk C栗子吧(第一百二十三回:C语言实例--显示变量和函数的地址)
- C语言预处理命令
- 程序员之---C语言细节22(函数返回指针注意事项<悬空指针>、查看进程能够分配的内存大小)
- C语言scanf函数详解
- 笔记:C语言图形基本函数及实例五子棋游戏
- C语言之文件操作06——写数据到文本文件遇0停止
- C语言函数參数传递原理
- C语言使用技巧(三十一):回顾strlen函数简单使用
- C语言实现结构体返回两值或多值:结构体定义函数的类型
- C语言之抽象数据类型(四十七)
- 函数指针 & 回调函数 & 面向对象风格的C语言
- C语言中为什么不能把char**赋给const char**
- C语言 Ubuntu系统 UTF-8 文字处理
- free()函数使用说明(C语言)
- C语言: 定义一个函数int isprime(int n),用来判别一个正整数n是否为素数,若为素数函数返回值为1,否则为0。在主函数中输入一个整数x,调用函数isprime(x)来判断这个整数x是
- C语言入门之函数