动态内存申请

我们先来看一张关于内存分布的图把

概述

数组的长度是预先定义好的,固定不变,但实际编程中,往往会发生所需的内存空间取决于实际输入的数据,而无法预先确定,所以c库提供了一些内存管理的函数,可以按需要动态分配内存空间。

静态分配和动态分配

1.静态分配

按事先规定大小分配内存空间,必须先知道所需空间大小,分配在栈区或全局变量区,一般以数组形式分配,按计划分配

2.动态分配

在运行中,根据需求自己分配空间,按需分配,分配在堆区,一般使用特定的函数进行分配。

动态分配函数(包含stdlib.h头文件)

1.malloc函数

void *malloc(unsigned int size)

功能:在内存的堆区(动态存储区)中分配块长度为size字节的连续区域,用存放类型说明符指定的类型使用时必须进行相应的强制转换,分配的空间里的内容不确定,一般使用memset初始化

返回值:分配空间的起始地址(成功申请)NULL(申请失败)

注意:在调用后要判断一下,是否申请成功

多次申请,第一次和第二次申请的内存不一定连续。

2.free函数

释放内存函数,void free(void *ptr),free函数释放ptr指向的内存。

注意:ptr指向的内存必须是malloc calloc realloc动态申请的内存。

char *p=(char *)malloc(100); free(p);释放后因为p没有再赋值,所以p还是指向原来动态申请的内存,但是内存已经不能再用了,p成了野指针。

一块动态申请的内存只能释放一次,不能多次释放。

3.calloc函数

void *calloc(size-t-nmemb,size-t-size)

功能:在内存的堆中,申请nmemb块,每块大小为size个字节的连续区域。

返回值:内存首地址(成功)NULL(失败)

注意calloc和malloc的区别:名字不一样,参数个数不一样,malloc申请的内存里的内容是随机的不确定的,而calloc申请的内存里内容为0

例:char *p=(char *)calloc(3,100):在堆申请三块,每块大小为100个字节,即300个字节的连续区域。

4.realloc函数

void *realloc (void *s,unsigned int newsize)重新申请内存

功能:例:char *p; p=(char *)malloc(100);

p=(char *)realloc(p,150)//在100个字节后追加50个字节

在原先s指向的内存基础上重新申请内存,新的内存大小为newsize个字节,如果原先内存有足够大的空间就追加

 

如果后边的内存不够用,则realloc函数会在堆区找一个newsize个字节大小的内存申请,将原先内存中的内容拷贝过来,然后释放原先的内存,最后返回新的内存的起始地址。

 

如果newsize比原先的内存小,则会释放原先内存后面的存储空间,只留前面的newsize个字节。

 注:malloc calloc realloc动态申请的内存,只有在free或程序结束时才释放。

4.内存泄漏

概念:申请的内存首地址丢了,找不到了,再也没法使用了,也没法释放了,这块内存就被泄露了,我们举几个例子来看看吧。

char *p;
p=(char *)malloc(100);
p="hello world";

这里p指向了别的地方了,我们并没有用一个新的指针来指向我们申请的内存地址,所以找不到申请的内存了,则发生了内存泄露。

再来看一个例子

void fun()
{
    char *p;
    p=(char *)malloc(100);
    .....

}
int main()
{
    fun();
    fun();
    fun();

}

这里每次调用了函数都会泄露100个字节的内存,因为没有在函数最后释放申请的内存。

解决方案1:调用后用free(p)释放内存

解决方案2:在fun函数最后将p地址返回到主函数 char *q,q=fun()

注意:申请的内存,一定不要把首地址丢了,在不用的时候释放掉才保险。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值