内存管理函数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. }

 

相关文章
|
21天前
|
程序员 C++
malloc与free的内存管理奥秘:技术分享
【8月更文挑战第22天】在软件开发过程中,内存管理是一个至关重要的环节。特别是在使用C或C++这类语言时,程序员需要手动管理内存的分配与释放。malloc和free函数是这一过程中的核心工具。本文将深入探讨malloc如何分配内存,以及free如何知道释放多少内存,帮助你在工作学习中更好地掌握这一技术干货。
44 4
|
23天前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
23天前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
29天前
【C初阶】内存函数:memcpy+memmove+memset+memcmp
【C初阶】内存函数:memcpy+memmove+memset+memcmp
|
23天前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
|
2月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
173 14
|
13天前
|
存储 监控 Docker
如何限制docker使用的cpu,内存,存储
如何限制docker使用的cpu,内存,存储
|
2月前
|
存储 固态存储 芯片
计算机中内存与存储
【7月更文挑战第28天】
32 1
|
2月前
|
存储 弹性计算 程序员
新手程序员如何阿里云服务器配置?新人开发者CPU内存带宽存储怎么选?
对于新手开发者、个人或学生选择阿里云服务器,推荐ECS经济型e实例(ecs.e-c1m1.large),适用于小型网站或轻量应用。配置2核2G内存、3M固定带宽、40G ESSD系统盘,仅99元/年且续费同价。
|
29天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储

热门文章

最新文章