一个奇怪的bug:
我在一个绘图系统中,设计了一个CLineItem类,其中有个记录数据的缓冲区m_pBuffer,在构造函数中有m_pBuffer= new float(m_lSize),而后我想将其清空,于是调用InitBuffer(),代码为
if (m_pBuffer)
{
   delete []m_pBuffer;
   m_pBuffer=NULL;
}
m_pBuffer= new float(m_lSize);
但退出程序,在析构函数释放内存时
if (m_pBuffer)
{
   delete []m_pBuffer;
   m_pBuffer=NULL;
}
发生Assertion,跟踪Debug发现m_pBuffe原来的地址为0X01809918在InitBuffer()中delete之后用new分配的地址为0X01808038,但在析构函数中释放内存时地址仍为0X01809918,就是说对已经释放的地址再调用delete当然会有Assertion发生。从代码上看没有什么问题,但不明白怎么会造成这样,请各位大仙帮帮忙,谢谢。

解决方案 »

  1.   

    看程序才知道。[email protected]
      

  2.   

    如果m_lSize没改变的话,用下面的方法清空:
    memset(m_pBuffer, sizeof(float)*m_lSize);
      

  3.   

    InitBuffer()有参数吗?是InitBuffer(float* _p)吗?这样不能释放的?要用**_pp才行啊
      

  4.   

    InitBuffer()没有参数,m_pBuffer是CLineItem的变量.
      

  5.   

    m_pBuffe原来的地址为0X01809918在InitBuffer()中delete之后用new分配的地址为0X01808038,但在析构函数中释放内存时地址仍为0X01809918为什么在InitBuffer中重新分配后是0x01808038,等你析构时它还是0x01809918??
      

  6.   

    1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。 
    2. 自定义消息及其他声明的标准写法 
    3. 使用调试宏时使用后最好注释掉 
    4. 尽量使用try - catch(...) 
    5. 尽量使用模块,不但表达清楚而且方便调试。
      

  7.   

    同意zhangnanonnet(鱼欢)的观点,我们程序员有时编程编着编着就有点迷信了,总是怀疑编译器有问题,呵呵,但是最后问题解决了,都会发现是自己的问题,呵呵,所以,永远不要怀疑编译器,只能怀疑自己,呵呵
      

  8.   

    按照我的经验,最好还是在OnDestroy里面释放,你试试看...
      

  9.   

    先郁闷一下。m_pBuffer = new float(m_lSize);
    上面一句明显有问题,作者的目的是要申请一个m_lSize个float类的变量,应该这样写
    m_pBuffer = new float[m_lSize];用new 申请的内存用delete[]来释放,当然会出错。
      

  10.   

    回复 yndfcd(YNDFCD),
    这是我贴帖子的笔误,不是程序的问题.或许是我程序的问题,但我查了很久都没有发现,回复kingyo(钝刀) 
    m_pBuffe原来的地址为0X01809918在InitBuffer()中delete之后用new分配的地址为0X01808038,但在析构函数中释放内存时地址仍为0X01809918为什么在InitBuffer中重新分配后是0x01808038,等你析构时它还是0x01809918??
    这是我单步调试时发现的,我也不明白为什么,程序运行到这里就异常.释放内存的问题,我用一个很笨的方法避免了异常,下次我把完整的代码贴上,大家帮忙看看.