复习C语言中内存开辟的知识

文章介绍了C语言中的内存管理函数malloc、calloc和realloc的用法,区分了堆和栈的概念,强调了内存分配和释放的重要性以及注意事项,包括内存泄漏和野指针问题。

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

一、函数原型说明

void *malloc(size_t Size);

malloc作用:申请一段内存空间,并且返回这个空间的首地址。

void*:该函数首地址返回类型为void*,可以把它强制转换成任意类型去使用。

Size:要申请的字节数。

例如:int *p = (int *)malloc(sizeof(int) * 10);

上述案例将定义一个类型指针p,指向新开辟的内存的首地址。通过使用malloc函数,将开辟内存为40的空间地址,并将返回类型强制转换为int类型。它其实相当于int a[10]。

如果内存分配失败,函数会返回0。失败的原因一般都会是内存不足导致的。

当然,既然开辟了内存空间,那么使用完成之后一定要释放,释放函数即free(p);

注意事项:

1、申请内存时,最好使用if语句判断内存是否申请成功,如if(p == NULL)。。。

2、当使用完毕后,一定要释放内存。在单片机中,如果我们使用内存后不释放,将会造成内存泄漏。在单片机无限while循环中,内存将一次次开辟,必定会导致空间不足程序崩溃。

3、释放完成后最好将指针置空,避免出现野指针。

二、哪里来的空间?

说到空间,我们必然会想到堆和栈。

       什么是堆?堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。

       什么是栈:栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

我是这样理解的,堆就是由程序员自己决定是否开辟和释放,栈的生命周期一结束就会被释放而堆内存会被垃圾回收机制不定时回收,栈一般都是存放一些临时的局部变量,在函数执行完毕后就会立即释放。而free()函数就是执行“垃圾回收”操作,哈哈。

三、扩展

C语言中还存在 calloc 和 realloc 函数,这些函数都有什么区别呢?

calloc函数和malloc函数基本上属于一模一样,只是参数不同的区别。例如

malloc函数:int* p = (int *)malloc(sizeof(int) * 10);

calloc函数:int *p = (int *)calloc(sizeof(int) , 10);

基本上是一模一样的,当然使用中,我们还是最习惯于使用malloc。

而realloc却有一些不同,realloc函数是在malloc函数的基础上去申请更大的内存空间。函数原型为:void* realloc(void* _Block, size_t Size);

例如:int* p = (int *)malloc(sizeof(int) * 10);     int *p1 = (int *)realloc(p , sizeof(int) * 20);              我们先是开辟了一段40字节的内存空间,然后使用realloc去申请了更大的80字节空间的大小,这就是realloc的用法。它的开辟过程是:

1、申请更大的80字节的空间,将首地址返回给p1;

2、将原本空间中的数据复制到新开辟的内存空间;

3、重点:realloc并不是在malloc空间内存的延续,而是新开辟的一段内存空间,然后将之间的40字节的空间大小释放掉,所以我们不用担心原空间后是否有足够的内存空间来延续,只需要判断是否新开辟成功即可。然后,使用完毕后仍然不要忘记释放指针指向的地址噢,不是释放指针!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值