【C语言】realloc()函数详解(动态内存开辟函数)

简介: 【C语言】realloc()函数详解(动态内存开辟函数)

一.realloc()函数简介

我们先来看一下cplusplus.com - The C++ Resources Network网站上realloc()函数的基本信息:

1.函数功能

可以看到,realloc()函数的功能是:更改动态分配的内存大小.

即便将内存块移动到新位置(异地扩容),之前内存块的内容也会随之转移到新的位置.但新开辟的部分是未被初始化的.

如我们使用malloc开辟并初始化5个整型,然后使用realloc扩容到10个整型后打印:


2.函数参数

该函数一共有2个参数,分别是:

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

1>.void* ptr

第一个参数的类型是无类型指针(void*),它指向一个要重新分配内存的内存块,该内存块是之前通过调用malloc,calloc或realloc进行动态分配内存的.

如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针.

2>.size_t size

第二个参数的类型是无符号整型(size_t),它表示新内存块的大小,以字节为单位.

如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。


3.函数返回值

void*

函数的返回值类型是无类型指针(void*),它的作用是在函数运行结束后返回指向重新分配大小的内存块的指针.如果请求失败了,则会返回一个空指针.


4.函数头文件

该函数包含在头文件<stdlib.h>中.


二.realloc()函数的具体使用

realloc()函数的使用场景是:当我们想调整先前使用malloc(),calloc()或realloc()函数开辟的动态内存的大小时,我们可以使用realloc()函数来实现这一诉求.

1.使用realloc()函数完成动态整型数组空间的扩容

如下,我们使用realloc()函数调整一个有10个元素的整型数组的大小将其改为15个整型元素.

分别给realloc()函数传入:动态开辟的内存块指针(即p),新内存块的大小(即15*sizeof(int)).

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
int main()
{
    int* p = (int*)malloc(10*sizeof(int));    //开辟10个整型大小空间
    if (p == NULL)       //如果开辟失败,则打印错误原因
    {
        //打印错误原因的一个方式
        printf("%s\n", strerror(errno));
    }
    else
    {
        int i = 0;
        for (i = 0; i < 10; i++)    //遍历并初始化打印这10个整型空间
        {
            *(p + i) = i;
            printf("%d ", *(p + i));
        }
        //可以正常使用p指针来操作这片空间了
    }
    printf("\n");
    int* p2 = (int*)realloc(p, 15 * sizeof(int));//将这块空间扩容到15个整型
    if (p2 == NULL)
    {
        printf("%s\n", strerror(errno));
    }
    else
    {
        int i = 0;
        for (i = 0; i < 15; i++)    //遍历并打印这15个整型空间
        {
            *(p2 + i)=i;
            printf("%d ", *(p2 + i));
        }
    }
 
    free(p);    //释放p的内存空间
    p = NULL;         //将指针p置为NULL,防止其变成野指针
 
    return 0;
}

在vs编译器中运行查看结果:

可见realloc()函数成功的将malloc()函数开辟的10个整形大小的空间改为15个整型大小的空间了.


2.使用()函数完成动态结构体空间的扩容

创建好结构体变量后,我们给calloc()函数传入:3 , sizeof(PeoInfo)(即3个PeoInfo类型大小的字节数).用来开辟好3个PeoInfo大小的结构体数组.


使用calloc()开辟好空间后我们使用realloc()函数将结构体数组的空间扩容到5个.

realloc()函数传入:ptr , 5*sizeof(PeoInfo)(即5个PeoInfo类型大小的字节数).

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
 
//人的信息-结构体
typedef struct PeoInfo
{
  char name[20];
  int age;
  char sex[5];
  char addr[20];
  char tele[11];//电话11位,留一位给'\0';
}PeoInfo;
 
typedef struct Contact
{
  PeoInfo* data;  //存放人的信息
  int sz;         //用来记录当前已经存放的信息的个数
  int capacity;   //记录当前通讯录的最大容量
}Contact;
 
int main()
{
  Contact con;
  PeoInfo* ptr = (PeoInfo*)calloc(3, sizeof(PeoInfo));   //动态开辟空间
 
  if (ptr == NULL)            //如果开辟失败,则打印错误原因
  {
    perror("InitContact::calloc");
    return;
  }
 
  PeoInfo*ptr2 = (PeoInfo*)realloc(ptr, 5 * sizeof(PeoInfo));
  if (ptr2 == NULL)
  {
    perror("InitContact::realloc");
    return;
  }
 
  free(ptr2);         //使用完后向系统归还动态开辟的内存空间
  ptr2 = NULL;              //将ptr2指针置为空,避免ptr2成为野指针
 
  return 0;
}

在vs编译器中查看结果:

可见realloc()函数成功的将结构体的元素个数由3个改为了5个.


三.realloc()的异地扩容

使用realloc()函数调整内存空间存在两种情况:

  1. 原有空间之后有足够大的空间
  2. 原有空间之后没有足够大的空间

如:图中绿色空间是我们之前动态开辟的内存空间,而现在我们想使用reallo函数将它扩容一倍,

黑色条代表内存条,红色空间代表被其他程序占用的空间,而紫色空间代表待扩容空间.

情况一:

当是情况一的时候,要扩展内存就原有内存之后直接追加空间,原来空间的数据不发生变化.

情况二:

当情况二的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址.


结语

希望这篇realloc()函数详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

有关更多动态开辟相关知识可以移步:

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!



C语言动态内存开辟相关库函数思维导图:


相关文章
|
4天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
25 6
|
18天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
31 6
|
1天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
19 6
|
1月前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
43 3
|
1月前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
27 0
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
392 0
|
2月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
64 1
|
2月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。