动态内存管理

1.动态内存分配

向内存申请空间的方式有两种方式

1.单个值                          2.一组值

int i=1;                           char arr[10]={0};

1)但开辟的空间大小是固定的,大小是不可变化的

2)数组在声明的时候,必须指定数组的长度,数组空间一旦确定了大小就不能调整

有时候我们需要的空间的大小在程序运行时才能知道,那数组开辟空间的方式就不能满足了,存在大(浪费),小(不够),刚刚好的情况

C语言引入了动态内存开辟,让程序员可以自己申请和释放空间,就可以比较灵活

2.malloc和free(maiioc和free都声明在stdlib.h头文件中)

2.1malloc

void * malloc ( size_t size);

参数的单位是字节

向内存申请一块连续可用的空间,并返回空间的起始地址

1)如果开辟成功就返回空间的起始地址

2)如果开辟失败就返回一个NULL指针,所以malloc的返回值一定要做检查

3)返回值的类型是void*,所以maloc不知道开辟空间的类型,具体在使用时再强制类型转换

4)如果参数size为0,malloc的行为是标准未定义的,取决于编译器

malloc申请的空间和数组的空间有什么区别

1.动态内存的大小是可以调整的

1.开辟空间的位置不一样

使用

2.2free函数

专门用来做动态内存的释放和回收的

void  free  ( void * ptr );

1)只用于动态申请的内存空间的释放和回收

2)如果ptr是空指针,则函数什么事都不做

err

 

  

3.calloc和realloc

3.1calloc

calloc函数也是用来动态内存分配的

void * calloc ( size_t num,size_t size);

1)为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0

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

如果我们对申请的内存空间的内容要求初始化,那么可以很方便地使用calloc函数来完成

3)申请的空间也是用free释放

使用

3.2realloc函数(调整内存空间)

realloc函数让动态内存管理更加灵活,可以做到对动态开辟的内存大小的调整

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

1)ptr是要调整的内存地址

2)size是调整之后的新大小

3)返回值是调整之后的内存起始地址

4)这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间

5)有两种情况

1.原有空间之后有足够大的空间

2.原有空间之后没有足够大的空间

使用

realloc开辟失败时,则不能拿p直接接收

附:

4.常见的动态内存的错误

4.1对NULL指针的解引用操作

4.2对动态开辟的空间越界访问

4.3对非动态开辟内存使用free释放

4.4使用free释放一块动态开辟内存的一部分

这里的free(p) p不再指向这块空间的起始位置,

*p=i;

p++;

从某个位置开始中途释放是不行的

要释放这块空间必须从头开始,给起始位置的地址

一旦让指针变化移动就会有问题

4.5对同一块动态内存多次释放

4.6动态开辟内存忘记释放(内存泄漏)

    

return直接返回函数  free没有机会释放

这块空间的地址放到p里面了,一旦回到主函数都不知道这块空间在哪里,想释放都释放不了

只有等主函数彻底结束这块空间才会回收

这块空间不使用了,但我们又不能对它进行释放

如果程序一直不执行,这块空间就再也找不到了就会造成内存泄露

内存泄漏:一块空间申请走了用完了不使用了但没有释放,没有释放,别人也用不到这块空间,而自己又不释放;也有可能是再也没办法释放,找不到这块空间(等于消失了)

可以返回这个函数的地址,让后来者得到这个地址再释放

5.题目

5.1题目1

正确的改法:

1)                                                                                   2)

      

5.2题目2

1)

int * f1(void)

{

    int  x=10;

     return (&x);                                返回栈空间地址的问题

}                                                       一旦有人接收了它的地址得到的就是野指针

2)

int  *  f2 (void)

{

     int * ptr;

     *ptr=10;                             没有初始化的指针怎么解引用?

     return ptr;                            ptr是野指针

}                               

5.3题目3

        存在内存泄漏的问题

                                                                                     没有free

                                                                          改正:

                                                                                    加上free(str);

                                                                                            str=NULL;

5.4题目4

6.柔性数组

它不是单独的一个数组而是一个结构体里面的成员

结构体中最后一个元素允许是未知大小的数组,这就叫做柔性数组成员

1)在结构体中

2)最后一个成员

3)未知大小的数组

typedef  struct  st_type

{

        int  i;

        int  a[ ];  //柔性数组成员

}type_a;

6.1柔性数组的特点

1)结构体中的柔性数组成员前面必须有至少一个成员

2)sizeof返回的这种结构大小不包括柔性数组的内存

3)包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应大于结构的大小,以适应柔性数组的预期大小

6.2柔性数组的使用

1)

2)

前20个是1~20,后面的则是随机值

如果是以%x的形式

方法1)方便内存的释放;

             连续的内存有益于提高访问速度,也有益于减少内存碎片

7.C中程序内存区域划分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值