double free 内存问题

标签: stringbuffer多线程list语言c
2010-05-20 10:42 10963人阅读 评论(0) 收藏 举报
 分类:
C/C++(32) 
double free
2008年06月02日 星期一 11:43
*** glibc detected *** free(): invalid pointer:
*** glibc detected *** malloc(): memory corruption:
*** glibc detected *** double free or corruption (out): 0x00000000005c18a0 ***
*** glibc detected *** corrupted double-linked list: 0x00000000005ab150 ***

你是否遇到过这样的情况,太沮丧了,程序总是无端coredump,gdb到core文件里面也看不出个所以然来,这对于一个大型的商业系统来说太令人恐怖了,事故随时可能发生。

遇到棘手的问题,慌张是没用的,解决不了任何问题。先坐下来,喝杯茶,舒缓一下神经。

内存问题始终是c++程序员需要去面对的问题,这也是c++语言的门槛较高的原因之一。通常我们会犯的内存问题大概有以下几种:

1.内存重复释放,出现double free时,通常是由于这种情况所致。
2.内存泄露,分配的内存忘了释放。
3.内存越界使用,使用了不该使用的内存。
4.使用了无效指针。
5.空指针,对一个空指针进行操作。

对于第一种和第二种,第五种情况,就不用多说,会产生什么后果大家应该都很清楚。

第四种情况,通常是指操作已释放的对象,如:
1.已释放对象,却再次操作该指针所指对象。
2.多线程中某一动态分配的对象同时被两个线程使用,一个线程释放了该对象,而另一线程继续对该对象进行操作。

我们重点探讨第三种情况,相对于另几种情况,这可以称得上是疑难杂症了(第四种情况也可以理解成内存越界使用)。

内存越界使用,这样的错误引起的问题存在极大的不确定性,有时大,有时小,有时可能不会对程序的运行产生影响,正是这种不易重现的错误,才是最致命的,一旦出错破坏性极大。

什么原因会造成内存越界使用呢?有以下几种情况,可供参考:
例1:
        char buf[32] = {0};
        for(int i=0; i<n; i++)// n < 32 or n > 32
        {
            buf[i] = 'x';
        }
        ....
        
例2:
        char buf[32] = {0};
        string str = "this is a test sting !!!!";
        sprintf(buf, "this is a test buf!string:%s", str.c_str()); //out of buffer space
        ....
        
例3:
        string str = "this is a test string!!!!";
        char buf[16] = {0};
        strcpy(buf, str.c_str()); //out of buffer space
        
类似的还存在隐患的函数还有:
        strcat,vsprintf等

同样,memcpy, memset, memmove等一些内存操作函数在使用时也一定要注意。
        
当这样的代码一旦运行,错误就在所难免,会带来的后果也是不确定的,通常可能会造成如下后果:

1.破坏了堆中的内存分配信息数据,特别是动态分配的内存块的内存信息数据,因为操作系统在分配和释放内存块时需要访问该数据,一旦该数据被破坏,以下的几种情况都可能会出现。 
        *** glibc detected *** free(): invalid pointer:
        *** glibc detected *** malloc(): memory corruption:
        *** glibc detected *** double free or corruption (out): 0x00000000005c18a0 ***
        *** glibc detected *** corrupted double-linked list: 0x00000000005ab150 ***

2.破坏了程序自己的其他对象的内存空间,这种破坏会影响程序执行的不正确性,当然也会诱发coredump,如破坏了指针数据。

3.破坏了空闲内存块,很幸运,这样不会产生什么问题,但谁知道什么时候不幸会降临呢?

通常,代码错误被激发也是偶然的,也就是说之前你的程序一直正常,可能由于你为类增加了两个成员变量,或者改变了某一部分代码,coredump就频繁发生,而你增加的代码绝不会有任何问题,这时你就应该考虑是否是某些内存被破坏了。

排查的原则,首先是保证能重现错误,根据错误估计可能的环节,逐步裁减代码,缩小排查空间。
检查所有的内存操作函数,检查内存越界的可能。常用的内存操作函数:
sprintf snprintf 
vsprintf vsnprintf
strcpy strncpy strcat 
memcpy memmove memset bcopy

如果有用到自己编写的动态库的情况,要确保动态库的编译与程序编译的环境一致。

保持好的编码习惯是杜绝错误的最好方式!

double free相关推荐

  1. 单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)...

    首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化. 但是Effective Java书中说过:除非绝对必要,否则就不要这么做. 1. DCL (double checked lockin ...

  2. java double转换符_java中字符串怎么转换成double类型

    展开全部 public class Demo { public static void main(String[] args) { Demo demo = new Demo(); String str ...

  3. java中将int转换float_在java中将float和double转换为int时有什么区别?

    我用这些语句来测试 float f=4.35f; int i=(int)(f*100); System.out.println(i); double d=4.35; i=(int)(d*100); S ...

  4. C语言:十六进制(HEX)和浮点类型(float、double)转换

    目录 1.浮点类型转换为十六进制 方法1:用地址用指针 方法2:用共用体 方法3: 使用memcpy 2.十六进制转换为浮点类型 近日在研究Modbus协议的时候遇到这样一个情况:使用ModScan3 ...

  5. double int char 数据类型

    贴心的limits... 测试代码: #include <iostream> #include <stdio.h> #include <limits> #inclu ...

  6. c++ double 只输出五位_c 语言第四章 在控制台上数据的输入和输出

    1 数据输出 我们之前已经使用过printf()函数来实现数据在控制台上输出 #include<stdio.h> int main(){printf("hello world&q ...

  7. swift string,Int,Double相互转换

    import UIKitvar str = "Hello, playground" // 1 字符串转Int Double Float var str1 = "818&q ...

  8. double和float计算精度不准的问题

    2019独角兽企业重金招聘Python工程师标准>>> 1.首先我们要知道float和double型,的底层实现是二进制的.十进制中的一个有限位数小数,转换成二进制就不一定是有限位数 ...

  9. java.sql.SQLException: Data truncation: Truncated incorrect DOUBLE value

    mysql 报这个异常:java.sql.SQLException: Data truncation: Truncated incorrect DOUBLE value update 表名 set c ...

  10. Java中比较两个Double类型数据的大小

    在java中int类型比较可以用"==",而double类型的数据不能用"= ="比较,否则得到永不相等的结果. 一般可以Double的doubleToLong ...

最新文章

  1. 重新认识 Delphi
  2. java 程序片段_20个非常有用的Java程序片段
  3. php 简繁体转换类库,OpenCC for PHP 优雅的简繁体转换
  4. java邻接表无向图的创建_邻接表无向图(三) 之Java详解
  5. muse ui tabs背景颜色字体颜色
  6. 【详细注释】1051 Pop Sequence (25 分)
  7. leetcode 65. 有效数字(正则表达式)
  8. [html] 移动端布局的自适应如何做?
  9. linux用户空间寄存器,在Linux用户空间中访问硬件寄存器
  10. webstorm更换主题后快捷键失效
  11. iOS开发--添加定位功能
  12. 黎曼ζ 函数中的Γ是否与欧拉B函数中的Γ一样
  13. spring-boot-starter-parent和spring-boot-dependencies的作用
  14. 各种转码(bytes、string、base64、numpy array、io、BufferedReader )
  15. php学习笔记——PHP 概述
  16. 信用评分卡建模:决策树模型
  17. 解决浏览器无法打开github官网的问题
  18. 90%的人都不知道的Node.js 依赖关系管理(上)
  19. R-RCN 论文理解3
  20. html文件剖析 - mdn学习

热门文章

  1. Java并发编程 Synchronized及其实现原理
  2. OSGI动态加载删除Service bundle
  3. git merge --squash改写提交
  4. mysql dba系统学习(12)mysql的数据文件 mysql dba系统学习(13)mysql的体系结构
  5. 卷积Groups Group Convolutions
  6. Windows XP Ghost系统安装
  7. 深度学习(二十二)Dropout浅层理解
  8. 【人脸识别】人脸识别必读论文
  9. 快速入门:十分钟学会Python
  10. Windows未能启动,原因可能是最近更改了硬件或软件,解决此问题的步骤