内存管理函数malloc,calloc,realloc详解

简介: 内存管理函数malloc,calloc,realloc详解

1.malloc

当我们想开辟一块动态内存空间的时候,就需要使用动态内存函数了,比如

char* p;

当我们想要使用地址p下的内存时,就需要用到malloc函数

void* malloc(size_t size);

注意,malloc函数的返回类型是(void*),形参是要开辟空间的字节数。所以要使用malloc这个函数,必须将返回值强制类型转换为想要的类型,比如

1. char* p1=(char*)malloc(10);//在p1这个地址下开辟10个字节空间,可以存放10个char型数据
2. int* p2=(int*)malloc(20);//在p2这个地址下开辟20个字节空间,可以存放5个int型数据

注意,malloc函数开辟内存空间有时会开辟失败,这时会返回空指针(NULL),所以,要较好的使用malloc函数,还要检查一下是否成功开辟内存,代码如下

1. int* p=(int*)malloc(20);//开辟内存空间
2. if(p==NULL)
3. {
4. printf("%s",strerror(errno));//打印开辟失败的原因
5. }

需要知道的是,malloc函数开辟的内存空间不会自动初始化,里面放的是随机值

1.  int* p = (int*)malloc(20);//开辟内存空间
2.  if (p == NULL)
3.  {
4.    printf("%s", strerror(errno));//打印开辟失败的原因
5.  }
6.  else
7.  for (int i = 0; i <5 ; i++)//访问新开辟的内存
8.  {
9.    printf("%d", (int)*(p + i));
10.   }

结果如下

malloc函数算是讲完了,但有一个非常重要的点并没有提到。我们知道创建一个数组相当于向内存空间申请了连续的一块空间,数组申请的内存空间是在栈上的,数组离开作用域会自动销毁,释放内存。

但是这里用malloc函数申请的内存空间是在堆上的,出作用域不会销毁,必须手动释放内存,否则会造成内存泄漏!(即使退出程序OS会自动回收内存,还是要有手动释放的好习惯)

手动释放内存需要使用free函数,free函数会把开辟的内存释放,内存的首地址就会变成野指针,所以还要将首地址置为空。代码如下

1. int* p = (int*)malloc(20);//开辟内存空间
2.  if (p == NULL)
3.  {
4.    printf("%s", strerror(errno));//打印开辟失败的原因
5.  }
6. //使用
7. 
8. //手动释放空间
9.  free(p);
10.   p = NULL;

2.calloc

不同于malloc的是,calloc函数会自动将新开辟的内存空间初始化为全0

void* calloc(size_t num,size_t size);

size_t num:开辟的个数

size_t size:开辟的类型大小

例如,开辟5个整型空间

1. #include<stdlib.h>
2. #include<errno.h>
3. #include<string.h>
4. #include<stdio.h>
5. int main()
6. {
7.  int* p = (int*)calloc(5,4);//开辟内存空间
8.  if (p == NULL)
9.  {
10.     printf("%s", strerror(errno));//打印开辟失败的原因
11.   }
12.   else
13.     //使用
14. 
15.   free(p);
16.   p = NULL;
17.   return 0;
18. }
19.

3.realloc

realloc函数用于原开辟的空间不足的情况下开辟更大的空间

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

void* ptr:原空间首地址

size_t size:新空间字节大小

realloc函数开辟新的空间会遇到两种情况

  1. 原空间后面空间充足,在原空间后面继续开辟新的空间,返回的地址和原地址相同。
  2. 原空间后面空间不足:
  • realloc会找到更大的空间
  • 将原来的数据拷贝到新的空间
  • 释放旧的空间
  • 返回新空间的地址(不同于原地址)
1. #include<stdlib.h>
2. #include<errno.h>
3. #include<string.h>
4. #include<stdio.h>
5. int main()
6. {
7.  int* p = (int*)calloc(5,4);//开辟内存空间
8.  if (p == NULL)
9.  {
10.     printf("%s", strerror(errno));//打印开辟失败的原因
11.   }
12.   else
13.     //使用
14.     for (int i = 0; i < 5; i++)
15.     {
16.       printf("%d ", *(p + i));
17.     }
18.   p=realloc(p, 40);//扩大内存空间,将20字节增到40字节
19.   for (int i = 0; i < 10; i++)
20.   {
21.     printf("%d ", *(p + i));
22.   }
23.   free(p);
24.   p = NULL;
25.   return 0;
26. }

 

相关文章
|
5天前
|
存储 编译器 程序员
【C/C++】动态内存管理(C:malloc,realloc,calloc,free)
探索C++与C语言的动态内存管理:从malloc到new/delete,了解内存分布及栈、堆的区别。文章涵盖malloc、realloc、calloc与free在C中的使用,强调内存泄漏的风险。C++引入new和delete,支持对象构造与析构,还包括operator new和placement-new。深入分析内存管理机制,揭示C与C++在内存处理上的异同。别忘了,正确释放内存至关重要!
|
10天前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
14 0
|
10天前
|
程序员 C语言
C语言内存管理:malloc、calloc、realloc与free函数详解
C语言内存管理:malloc、calloc、realloc与free函数详解
8 0
|
22天前
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之 从Kafka读取数据,并与两个仅在任务启动时读取一次的维度表进行内连接(inner join)时,如果没有匹配到的数据会被直接丢弃还是会被存储在内存中
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
14天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
23 2
|
18天前
|
存储
数据在内存中的存储(2)
数据在内存中的存储(2)
26 5
|
18天前
|
存储 小程序 编译器
数据在内存中的存储(1)
数据在内存中的存储(1)
30 5
|
18天前
|
存储 安全 Java
SpringSecurity6从入门到实战之初始用户如何存储到内存
Spring Security 在 SpringBoot 应用中默认使用 `UserDetailsServiceAutoConfiguration` 类将用户信息存储到内存中。当classpath有`AuthenticationManager`、存在`ObjectPostProcessor`实例且无特定安全bean时,此配置生效。`inMemoryUserDetailsManager()`方法创建内存用户,通过`UserDetails`对象填充`InMemoryUserDetailsManager`的内部map。若要持久化到数据库,需自定义`UserDetailsService`接口实
|
17天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
19 2
|
17天前
|
存储
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)