常见的内存错误及其对策(※)

    指针是C语言最强大的特性之一, 但也是最危险的特性之一: 误用指针导致的错误通常难以定位, 且后果严重. 常见的内存异常错误主要有两类, 一类是非法内存访问错误, 即代码访问了不该访问的内存地址; 另外一类是由于持续的内存泄漏导致系统内存不足, 编译器往往不易发现这类错误, 在程序运行时才能捕捉到: 这类错误通常是时隐时现的, 这就进一步增加了对这类错误的排错难度. 下面我们就来介绍一些常见的内存错误及其解决对策.

       前四种错误都属于内存非法访问错误, 即代码访问了不该访问的内存地址. 在现代操作系统严格的进程管理体系下, 非法内存访问的结果大多时候是不会引起诸如死机、硬盘冒烟、显示器爆炸这样极端严重的后果的. 一般而言, 这类错误要么产生莫名其妙的结果, 要么是操作系统友好地宣告你的程序得了不治之症, 是接受安乐死的时候了. 

      下面首先来看第一类常见的内存错误.

      在申请动态内存时, 找不到足够大的内存块, 说明系统内存此时已经耗尽, 相应地内存申请操作就会失败. 系统宣告内存申请失败的方法是让malloc函数返回一个空指针. 我们可以在使用动态申请的内存前通过检查malloc函数的返回值来应对该问题: 一旦发现malloc函数返回的是空指针, 就用exit函数立即结束程序的运行. 如果是在一个函数内申请动态内存, 也可以用return语句终止这个函数的执行: 如果这个函数内的其他地方也申请了动态内存, 这种从函数返回的方式就显得有些力不从心了——在用return语句从函数返回之前, 必须要将已经申请成功的内存全部释放掉才能从函数返回. 一般来说, 如果内存耗尽现象发生, 那么应用程序基本上已经无药可救了, 此时如果不用exit将坏掉的程序杀死, 那么它有可能会害死操作系统. 

        如果形参是指针变量, 也可以在函数的入口处用断言assert来检查指针变量是否为空指针, 当然这种方法仅适用于程序调试阶段. 

        第二类常见的错误就是内存分配成功, 但没有初始化就将其作为右值使用——如此也许不会造成系统崩溃, 但有可能使程序的行为发生异常, 输出一些乱码. 犯这种错误的主要原因是程序员没有初始化的观念, 误以为内存的默认值全为0. 虽然有时内存的默认值确实为0, 但我们应该宁可信其无而不可信其有, 即不要忘记给申请的内存赋初值, 如此会给后续的使用带来方便. 

       第三类错误是内存分配成功, 并且已经初始化, 但操作越界. 例如使用数组时常发生下标"多1"或"少1"的操作, 特别是当循环次数较多时, 由于处理不当, 我们有时会越界访问数组. 再如我们使用malloc函数为长度为n的一维动态(整数)数组申请动态内存时, 假如整型变量占用的空间未知(可能是2 bytes可能是4 bytes), 若整型变量占用4 bytes, 直接用语句 p = (int*)malloc(2 * n) 申请的动态内存空间就不足以放得下n个整型变量, 这样我们后面往动态数组中存放数据时, 就会发生越界访存的严重后果. 在使用循环语句遍历n个元素的数组时, 注意数组下标是从0开始的,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

好梦成真Kevin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值