《C语言深度解刨》阅读笔记 Ⅴ

第五章、内存管理

  • 为防止野指针,将指针初始化和使用后为NULL。
  • 栈、队和静态区
    静态区:保存自动全局变量和static 变量(包括static 全局和局部变量)。静态区的内容
    在总个程序的生命周期内都存在,由编译器在编译的时候分配。
    栈:保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容
    也会自动被销毁。其特点是效率高,但空间大小有限。
    堆:由malloc 系列函数或new 操作符分配的内存。其生命周期由free 或delete 决定。
    在没有释放之前一直存在,直到程序结束。其特点是使用灵活,空间比较大,但容易出错。
  • 指针没有指向一篇合法内存的常见错误:
    ①结构体成员指针未初始化;
    ②没有为结构体指针分配足够的内存空间;
    ③函数的入口检验(不管什么时候,我们使用指针之前一定要确保指针是有效的。)
    一般在函数入口处使用assert(NULL != p)对参数进行校验。在非参数的地方使用
    if(NULL != p)来校验。但这都有一个要求,即p 在定义的同时被初始化为NULL 了。
  • assert 是一个宏,而不是函数,包含在assert.h 头文件中。如果其后面括号里的值为假,
    则程序终止运行,并提示出错;如果后面括号里的值为真,则继续运行后面的代码。这个
    宏只在Debug 版本上起作用,而在Release 版本被编译器完全优化掉,这样就不会影响代码
    的性能。
  • assert 宏只是帮助我们调试代码用的,它的一切作用就是让我们尽可能的在调试函数的时候
    把错误排除掉。参数出现错误并非本函数有问题,而是调用者传过来的实参有问题。assert 宏可以帮助我们定位错误,而不是排除错误。
  • 为指针分配内存太小——导致越界行为。
    例:在字符串拷贝时,忘记结束标志“/0”导致拷贝后的数据出错,解决办法是是加上这个字符串结束标志符:char *p2 = (char *)malloc(sizeof(char)*strlen(p1)+1*sizeof(char));
  • 内存泄漏
    会产生泄漏的内存就是堆上的内存(这里不讨论资源或句柄等泄漏情况),也就是说由
    malloc 系列函数或new 操作符分配的内存。如果用完之后没有及时free 或delete,这块内存
    就无法释放,直到整个程序终止。
  • malloc 函数的原型:(void *)malloc(int size)。
  • 使用malloc 函数需要几个要求:
    ①内存分配给谁?
    ②分配多大内存?
    ③是否还有足够内存分配?
    ④内存的将用来存储什么格式的数据,即内存用来做什么?
    ⑤分配好的内存在哪里?
  • 使用malloc后,记得用if(NULL!=p)检验是否分配成功。
  • malloc 函数可以申请0 字节内存,函数并不返回NULL,而是返回一个正常的内存地址。但是你却无法使用这块大小为0 的内存,并且if(NULL != p)语句校验将不起作用。
  • 内存释放
    既然有分配,那就必须有释放。
    要注意对应关系。
  • 使用free 函数之后指针变量p 本身保存的地址并没有改变,需要重新把p
    的值变为NULL。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七十二旹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值