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

文章目录

  • 前言
  • 一、认识了解realloc函数
  • 二、使用realloc函数
    • 解析
    • 1)关于缩容的问题

前言

有时我们觉得我们用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#include#include#includeint 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的大小,可不可以做到缩容来节省空间呢?
它有可能会原地缩容,也有可能会异地缩容。但我们一般不考虑缩容的问题,因为如果系统是异地缩容,它需要找一块空间,把原数据考虑过来,然后再把原空间释放,这样会有性能,时间上的代价。而且如果我们之后又要插入数据,那我们又要进行扩容。
总结一下来说:
缩容:以时间换空间
不缩容:以空间换时间