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

1.malloc

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

char* p;

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

void* malloc(size_t size);

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

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

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

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

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

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

结果如下

 

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

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

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

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

    //手动释放空间
	free(p);
	p = NULL;

 2.calloc

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

void* calloc(size_t num,size_t size);

size_t num:开辟的个数

size_t size:开辟的类型大小

例如,开辟5个整型空间

#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<stdio.h>
int main()
{
	int* p = (int*)calloc(5,4);//开辟内存空间
	if (p == NULL)
	{
		printf("%s", strerror(errno));//打印开辟失败的原因
	}
	else
		//使用

	free(p);
	p = NULL;
	return 0;
}

3.realloc

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

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

void* ptr:原空间首地址

size_t size:新空间字节大小

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

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

猜你喜欢

转载自blog.csdn.net/2301_76144863/article/details/129979308