动态内存二

动态内存管理

那么我们就要引用动态内存这个概念 ——动态内存(Dynamic Memory),使用户能够指定虚拟操作系统启动的RAM容量,并将平台可用的系统内存最大化。

申请动态内存是在堆区中申请,而堆区对于用户是要自己管理的。

我们这里介绍几个涉及动态内存的函数,这些函数都是在#include<stdlib.h>工具包中

malloc(),这个函数的作用是申请一块指定大小的连续的内存空间

传递的参数是void *(size_t size)

例如int *p=(int*)malloc(sizeof(int)*n)

这就在堆区中申请了n个int大小的内存空间

前面提到,堆区的内存是要求使用者自己管理的

在使用完之后还要进行释放操作,如果不进行释放,那么下一次要使用的时候就不能再次使用这一块地方

因此后面都要跟上free(p),意思是释放掉p指向的内存空间

同时要对p=NULL;这一步是为了防止多次free导致访问到了不允许访问的地址引起指针崩溃的情况。
memset(),这个函数的作用是未初始化的内存进行初始化,传入参数为(void *,int value,size_t size)

特别要注意的是,这里传入的size是字节数

例如

int *p=(int *)malloc(sizeof(int)*10);

memset(p,0,sizeof(int)*10);

那么这就为申请到的未初始化的内存进行了初始化。那么这里有一个问题,依据传入的参数,我们将内存初始化为全为0,那么可不可以是1呢

其实是不可以的

0,1分别在内存上按00000000和01010101存储的,那么对应的1存入内存中就不是1了。

calloc(),这个函数的作用是用来申请具有初始化的连续的内存空间,传入参数是(int value,size_t size)。

int *p=(int*)calloc(0,sizeof(int)*10);

这里就申请到了具有初始化的连续的内存空间

realloc(),这个函数的作用是对内存进行扩容操作,传入参数是(void *,size_t size)

例如

int*p=(int *)malloc(sizeof(int )*10);

int *q=(int*)realloc(p,sizeof(int)*15);

这就把p从10个int 扩容成了15个int

但是进行扩容操作,这就涉及到了几个问题

第一,后续内存空间足够,可以扩容

第二,堆内存不足,扩容失败

第三,后续堆内存不足,不能分配,那么关于这个情况,堆内存就会有新的解决方案,他会自己找一块足够大的新的地方,然后再将原来的值复制过去,就完成了扩容。

我们来观察以下代码中的错误

 示例1就是一个完整的malloc申请内存空间的过程

示例2有错误,是因为int *ip实际上是在栈当中操作内存,而free是对堆内存的操作,面对的对象不同,所以会有这样的问题

示例3在释放了申请的内存后再对原内存进行操作,实际上就是访问了不该访问的内存空间,会发生指针崩溃

示例4是访问了不允许访问的内存,会引发程序崩溃

示例5是用下标访问申请内存是,多访问了一个没这样也是访问到了不允许访问的内存

示例6是移动了指针的指向,会访问到不允许访问的内存

示例7如果要把在函数体内申请的堆内存拿到主程序中使用的话,我们应该要返回它,例如

这样就可以正确的访问到了

如果在函数体内定义一个局部变量,这个是不能返回的,因为在程序结束指针这个区域也就消失了,所以是不可以返回的

 

 

 这里的第一个就可以和示例7联系

而二三,也就是不能返回局部变量的问题。

参考:图论教育之动态内存管理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值