动态内存分配函数

目录

一.静态内存分配和动态内存分配

二.动态内存分配函数

1.malloc

2.free

3.calloc

4.realloc


一.静态内存分配和动态内存分配

静态内存分配:静态内存分配的空间都是固定的大小,且分配的是栈区的空间,函数执行结束时这些存储单元自动被释放

动态内存分配:在程序执行的过程中动态地分配或回收存储空间。动态内存分配的是堆上的内存,堆上分配的内存不会主动释放,需由程序员自己释放或是在程序结束时还给操作系统。

内存区域分区

 

栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。

堆区(heap):一般由程序员自己分配释放,若程序员不释放,程序结束时可能由OS回收

静态段(静态区)(static):存放全局变量、静态数据/程序结束后由系统释放。

代码段:存放函数体(类成员函数和全局函数)的二进制代码。

二.动态内存分配函数

在使用动态内存分配函数时,需引用对应头文件(#include <stdlib.h>

1.malloc

void* malloc(size_t size);

函数的功能:向内存申请一块连续可用的空间,并返回指向这块空间的指针。

若开辟成功,则返回一个指向开辟好空间的指针;若开辟失败,则返回一个NULL指针(因此一定要对malloc函数的返回值进行检查

函数的返回值类型为void*,所以malloc函数并不知道开辟空间的类型,由使用者在使用的时候决定

若参数size为0,此时malloc的行为是标准未定义的,取决于编译器。

#include <stdlib.h>
#include <stdio.h>

int main()
{
	int* p = (int*)malloc(40);
	//对返回值进行检查
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}

	for (int i = 0; i < 10; i++)
	{

		printf("%d\n", *(p + i));
	}
	//释放动态开辟的内存
	free(p);
	p = NULL;
	return 0;
}

malloc函数不会对空间进行初始化,因此存放内容为随机值 

2.free

void free(void* ptr)

free函数是用来释放动态开辟的内存的。

若参数ptr指向的空间不是动态开辟的,那么free函数的行为是未定义的

若ptr是NULL指针,那么函数什么事都不做

注:在释放动态开辟的内存后,应将ptr置为NULL,因为ptr指针指向的动态开辟的空间已经被释放了后,若ptr仍指向那块空间,后面若使用了ptr访问指向的空间,则非法访问该内存。

3.calloc

void* calloc(size_t num, size_t size)

函数的功能:为num个大小为size的元素开辟一块内存空间,并且把空间的每个字节初始化为0.

calloc函数与malloc函数的区别只在于calloc函数会在返回地址之前将申请的空间的每个字节全部初始化为0

#include <stdlib.h>
#include <stdio.h>

int main()
{
	int* p = (int*)calloc(10, 4);
	//对返回值进行检查
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}

	for (int i = 0; i < 10; i++)
	{

		printf("%d\n", *(p + i));
	}
	//释放动态开辟的内存
	free(p);
	p = NULL;
	return 0;
}

calloc函数会将空间的每个字节初始化为0

 

4.realloc

void* realloc(void* ptr ,size_t size)

realloc函数的功能:

若申请的空间过小或是过大,则可用realloc函数对内存大小进行调整。

ptr:要调整的内存地址

size:要调整之后的大小

在增加空间时,若原本开辟的内存后面有足够的空间,则直接在后面开辟新的空间;

若后面的空间不够,则realloc会先开辟新的空间,并将旧空间中的数据拷贝到新的空间中,拷贝后则释放旧的空间,最后返回新空间的起始地址

若开辟失败,则返回NULL,因此应先对返回值进行判断,防止原始数据丢失

#include <stdlib.h>
#include <stdio.h>

int main()
{
	int* p = (int*)calloc(10, 4);
	//对返回值进行检查
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}

	int* ptr = (int*)realloc(p, 20*sizeof(int));
	//判断ptr是否为NULL
	if (ptr != NULL)
	{
		p = ptr;
		ptr = NULL;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	for (int i = 0; i < 20; i++)
	{
		printf("%d\n", *(p + i));
	}
	//释放动态开辟的内存
	free(p);
	p = NULL;
	return 0;
}

 realloc函数也不会对新开辟的空间进行初始化

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠枬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值