C语言1. 动态内存管理+这类读代码题

  1. 为什么存在动态内存分配:
    普通的内存开辟方式开辟空间后,比如数组大小,就不能改变了。要么开大了,要么开小了
    请添加图片描述

动态内存管理的方法:
malloc()、free()、calloc()、realoc()

内存中,空间的使用规则为:
请添加图片描述
如上图,内存管理使用的函数操作都在堆区上

malloc():返回无类型指针void*

  • 无空间时,给你返回NULL
  • 它返回void* ,但是你可以强制转换
  • 返回后的空间内容,可以随便给值

free():释放

  • malloc()申请后的初始用p接收,但使用过这片空间后,p可能不在初始位置,所以一般使用前先存一个ptr= p,最后free(ptr);
    释放之后,ptr还指向那里,ptr是野指针,给它置空
    所以一般释放+置空
free(p);
p = NULL;
  • 如果没有free malloc的空间,程序结束,操作系统会自动回收,但是程序一直允许24h,会造成内存泄漏的问题。
// 检查有没有申请好
if(p==NULL)
{
	perror("calloc");
	return 1;
}

calloc():申请数组,初始化为0

申请10个整形数组空间,这里申请的空间会初始化为0
int* p = (int*)calloc(10, sizeof(int));

一般calloc()和malloc()后面检查有没有开辟成功

// 检查有没有申请好
if(p==NULL)
{
	perror("calloc");
	return 1;
}

realloc():动态内存管理更灵活,再开辟

  • 空间不够后,再扩容
int *p = (int*)malloc(40);
// 空间不够后,再扩容
p = realloc(p, 80);

  • 它对p扩容后返回位置:
    当追加发现可能会把别的变量空间占用的话,它会再往后找一片更大空间,并且改变原始p的位置,且拷贝之前数据,且还会把旧的空间free(),返回值是新空间地址。
  • 如果扩容失败,realloc会返回NULL,如果直接用p,把之前的空间p也丢掉了,所以定义新指针去接收返回
int *ptr = (int*)realloc(p, 20);
if(ptr==NULL)
{扩容失败}

注意事项:

malloc和realloc后,都需要对原始指针做NULL判断
 free(p\)时,注意p值是否是p初始位置
对同一块内存多次释放,也出错

且要注意越界访问,如下创建100个字节空间,只能存25个整型,但是这里<=25,越界了
请添加图片描述
读代码:
程序1
请添加图片描述
分析:
getMemory()传了str,str是NULL,函数中p是str临时拷贝,p也是NULL,给p申请了空间,函数执行完,p被销毁了,但是申请的空间却没释放,内存泄漏而str还是NULL。
然后main()中strcpy中对NULL解引用,程序崩溃。
问题原因:str本身是NULL,且接收它的是形参,拷贝了NUL。
但是如果你要改变str本身,Get函数中,用二级指针来接收做操作就没问题。
内存泄漏
程序2
请添加图片描述
Get函数出去后,hello空间就没了,虽然str记着那片地址,但它是野指针,它打印了乱码,野指针可能正常,也可能报错。(返回栈空间地址问题)
有时候野指针访问到值是对的,因为那片旧的区值还未被使用,值为被覆盖,可能得到对的,但程序如果多写几行,函数栈帧会中存新的内容,访问就不一定是之前的值了。
程序4
请添加图片描述
str不为NULL,会进去strcpy又改值为world,所以错了,野指针,所以free(str)后记得置NULL

程序5
请添加图片描述
ptr指针没有初始化就使用,野指针问题

======================================
C/C++程序如何开辟空间:
内存中不只是栈区、堆区(动态管理使用)、静态区(数据段),还有内核区,代码段(为了执行代码),用户代码不能读写

请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值