C语言动态内存管理

本文介绍了C语言中动态内存管理的概念,包括malloc、calloc和realloc函数的使用。动态内存分配允许在程序运行时确定内存大小,malloc用于分配内存,calloc在分配内存的同时初始化为0,realloc则用于调整已分配内存的大小。文章还列举了动态内存管理中常见的错误,如对NULL指针解引用、越界访问等,并强调了内存释放的重要性,防止内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态内存分配


前言


一、为什么存在动态内存分类

我们知道的内存使用方式:
1.创建一个变量
int a = 10; //局部变量——栈区
int g_a = 10; //全局变量——静态区
2.创建一个数组
arr[10] = {0}; 如果是全局变量存放于栈区,如果是局部变量存放于静态区
图片在这里插入图片描述C语言内存的简单分布
上述的两个方式有两个特点:
1.空间开辟的大小是固定的
2.数组在申明的时候必须指定数组的长度,其所需要的内存在编译时分配
但是有时候我们需要的空间大小在程序运行时才能知道,这时候就需要试试动态内存开辟了

二、动态内存函数使用及常见的动态内存错误

1.malloc和free

malloc函数:void *malloc( size_t size );
此函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
注意:1.如果开辟成功,返回一个指向开辟好的空间的指针
2.开辟失败,返回一个NULL指针,因此malloc的返回值一定要做检查
3.返回类型是void *,所以malloc函数并不知道空间开辟的类型,具体在使用的时候使用者自己来决定

free函数:void free( void *memblock );
free函数专门做动态内存的释放和回收的

#include<string.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(10*sizeof(int))//向内存申请10个整型的空间40个字节
	if (p == NULL)
	{
		return 0;//开辟内存失败 函数返回空指针
	}
	else
	{
		//正常使用开辟的空间
	}
	//当动态申请的空间不再使用时就应该还给操作系统
	free(p);
	p = NULL;
	return 0}

2.calloc

void *calloc( size_t num, size_t size );
calloc函数功能时为num个大小为size的元素开辟一块空间,并且把空间每个字节初始化为0. (与malloc的区别在于会把申请的空间的每个字节初始化为0)

int* p = (int*)calloc(10, sizeof(int));//向内存申请10个整型的空间40个字节
if (p == NULL)
	{
		return 0;//开辟内存失败 函数返回空指针
	}
	else
	{
		//正常使用开辟的空间
	}
	free(p);
	p = NULL;

3.realloc

void *realloc( void *memblock, size_t size );
memblock 要调整的内存块地址 size 调整之后的新大小
注意:1.返回值为调整之后的内存起始位置。
2.此函数在调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。

int* p = (int*)malloc(20);
if (p == NULL)
{
	return 0;
}
else
{
	//正常使用开辟的空间
}
//假设malloc开辟的20个字节空间不够用 我们希望有40个字节的空间  就可以使用realloc调整
int* p2 = realloc(p, 40);

realloc在调整内存空间时存在两种情况:
情况1:如果p指向的空间之后有足够的内存空间可以追加,则直接追加后返回p
情况2:如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一个新的内存区域开辟一块满足需求的空间,并且把原来内存空间的数据拷贝回来,释放旧的内存空间,最后返回新开辟的内存空间地址。

还有一个注意事项:用一个新的变量来接收realloc函数的返回值

//p = realloc(p, INT_MAX);  这里如果用p接收p = NULL 就完全改变了p
int* ptr = realloc(p, INT_MAX);//要调整的太大,调整失败 返回NULL给ptr判断
if (ptr != NULL) 
{
	p = ptr//如果调整成功就重新给p
}
free(p);
p = NULL;

常见的动态内存错误

一定要避免的错误
1.对NULL指针解引用操作
2.对动态开辟空间的越界访问
3.对非动态开辟内存使用free
4.使用free释放动态开辟内存的一部分
5.对同一块动态内存的多次释放
6.动态开辟内存忘记释放(内存泄漏)

int *p = (int *)malloc(INI_MAX/2);
*p = 100;//如果p的值是NULL就会出问题  对NULL指针解引用了
free(p);

//正确写法
int *p = (int *)malloc(INI_MAX/2);
if(p == NULL)
{
	return 0;
}
else
{
	//正常使用
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了动态内存这块,就是自己平时上课时的笔记和一些心得。

希望对看到的大家有所帮助!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值