常见的内存错误及其对策


  • 发生内存错误,编译器不能发现这些错误,在程序运行时才能捕捉到。而且时有时无
  • 内存分配未成功,确使用了它
  • 产生原因: 内存不足。
  • 解决办法:在使用内存之前检查指针是否为null,如果指针p是函数形参,那么在函数的入口处用**断言:**assert(p!=null);这个语句的作用,如果p!=null,则通过。如果new/malloc,应该用if(p==null),进行预防处理。
  • 内存分配成功,但是未初始,就引用它
  • 产生原因:
  • 没有初始化的概念
  • 误以为内存的缺省初值全为0(内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有)。
  • 解决办法:无论用何种方式创建数组,都被忘了赋初值,即使赋0值也不可省略。
  • 内存分配成功并且已经初始化,但是操作越过了内存的边界
  • 产生原因:在使用数组时经常发生下标多一或者少一的操作。特别是在for循环中。
  • 解决办法:小心仔细。
  • 忘记释放内存,造成内存泄露
  • 产生原因: 忘记free,忘记delete。
  • 造成的影响: 这种错误,每发生一次,就丢失一块虚拟内存(内存泄露),但是当虚拟内存耗尽时, 程序会突然死掉。
  • 解决办法:小心仔细,或者自己写一个方法,登记程序中动态申请的所有内存,然后根据需要释放。
  • 释放了内存却继续使用它
  • 产生原因:
  • 程序中的对象调用关系过于复杂,难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。
  • 函数return语句写错了,注意不要返回指向“栈内存”的指针或者引用,因为该内存在函数体结束时理论上被自动销毁。
  • 使用free或者delete释放了内存后,没有将指针设置为null,导致产生野指针。
  • 解决办法:
  • 防止操作空指针:用malloc或者new申请内存之后,应该立即检查指针是否为null。
  • 防止将未初始化的内存作为右值使用:不要忘记为数组和动态内存赋初值。
  • 防止数组越界。
  • 防止内存泄露:malloc和free,new和delete配对。
  • 防止产生野指针:用free和delete释放内存后,立即将指针设置为null。

出现段错误的6中情况


  • 操作非法指针,指针未初始化或者释放内存之后再次访问。
  • 操作NULL指针。
  • 修改常量区中的内容。char *p = "helloworld";p[1]=a;
  • 数组越界(并非数据越界一定会报错)。
  • 多次释放同一块内存。
  • 跨进程访问某个地址。