C语言中realloc函数解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: C语言中realloc函数解析

真是有点惭愧,这些内容本应该很早就掌握的,以前只是糊里糊涂的用,不知道在内存中具体是怎么回事,现在才弄清楚。

realloc(void *__ptr, size_t __size):更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。

如果将分配的内存减少,realloc仅仅是改变索引的信息。

如果是将分配的内存扩大,则有以下情况:

1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。

2)如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。

3)如果申请失败,将返回NULL,此时,原来的指针仍然有效。

注意:如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放掉原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。

看一下示例代码

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[], char* envp[])
{
  int input;
  int n;
  int *numbers1;
  int *numbers2;
  numbers1=NULL;
  if((numbers2=(int *)malloc(5*sizeof(int)))==NULL)//为numbers2在堆中分配内存空间
  {
    printf("malloc memory unsuccessful");
    exit(1);
  }
  printf("numbers2 addr: %8X\n",(int)numbers2);
  for(n=0;n<5;n++) //初始化
  {
    *(numbers2+n)=n;
    //printf("numbers2's data: %d\n",*(numbers2+n));
  }
  printf("Enter new size: ");
  scanf("%d",&input);
  //重新分配内存空间,如果分配成功的话,就释放numbers2指针,
  //但是并没有将numbers2指针赋为NULL,也就是说释放掉的是系统分配的堆空间,
  //和该指针没有直接的关系,现在仍然可以用numbers2来访问这部分堆空间,但是
  //现在的堆空间已经不属于该进程的了。
  numbers1=(int *)realloc(numbers2,(input+5)*sizeof(int));
  if(numbers1==NULL)
  {
    printf("Error (re)allocating memory");
    exit(1);
  }
  printf("numbers1 addr: %8X\n",(int)numbers1);
  /*for(n=0;n<5;n++) //输出从numbers2拷贝来的数据
  {
    printf("the numbers1's data copy from numbers2: %d\n",*(numbers1+n));
  }*/
  for(n=0;n<input;n++)//新数据初始化
  {
    *(numbers1+5+n)=n+5;
    //printf("numbers1' new data: %d\n",*(numbers1+5+n));
  }
  printf("\n");
  free(numbers1);//释放numbers1,此处不需要释放numbers1,因为在realloc()时已经释放
  numbers1=NULL;
  //free(numbers2);//不能再次释放
  return 0;
}

如果当前内存段后有足够的空间,realloc()返回原来的指针:

yugsuo@ubuntu:~/linux/memange$ gcc -g -o realloc realloc_example.c 
yugsuo@ubuntu:~/linux/memange$ ./realloc 
numbers2 addr:  8AFC008
Enter new size: 10
numbers1 addr:  8AFC008

如果当前内存段后没有足够的空间,realloc()返回一个新的内存段的指针:

yugsuo@ubuntu:~/linux/memange$ ./realloc 
numbers2 addr:  9505008
Enter new size: 1000000
numbers1 addr: B716F008


目录
相关文章
|
21天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
105 14
|
25天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
49 10
|
25天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
43 9
|
25天前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
34 8
|
25天前
|
C语言 开发者
【C语言】数学函数详解
在C语言中,数学函数是由标准库 `math.h` 提供的。使用这些函数时,需要包含 `#include <math.h>` 头文件。以下是一些常用的数学函数的详细讲解,包括函数原型、参数说明、返回值说明以及示例代码和表格汇总。
43 6
|
25天前
|
存储 C语言
【C语言】输入/输出函数详解
在C语言中,输入/输出操作是通过标准库函数来实现的。这些函数分为两类:标准输入输出函数和文件输入输出函数。
178 6
|
25天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
54 6
|
25天前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
34 5
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
42 3
|
25天前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
35 5

推荐镜像

更多