【问题标题】:Crash when using delete [] to delete a pointer使用 delete [] 删除指针时崩溃
【发布时间】:2016-03-11 00:09:02
【问题描述】:

我用来输出 pTemp 的代码:

if (m_pTImgFrame != NULL)
{
    for (int i = 0; i < m_nFrameNumber; i++)
    {
        TImage* pTemp = (TImage*)m_pTImgFrame[i];
        if (pTemp != NULL)
        {
            TCHAR buffer[256] = { 0 };
            _stprintf_s(buffer, 256, _T("%d,%d,%d,%d,%d,%d,%d,%d\n"), 
                pTemp->attrib,
                pTemp->h,
                pTemp->pitch,
                pTemp->w,
                pTemp->data[0],
                pTemp->data[1], 
                pTemp->data[2], 
                pTemp->data[3]);
            OutputDebugString(buffer);

            delete[] pTemp;
            m_pTImgFrame[i] = NULL;
        }
    }
    delete []m_pTImgFrame;
    m_pTImgFrame = NULL;
}

仍然崩溃

origin代码
if (m_pTImgFrame != NULL)
{
    for (int i = 0; i < m_nFrameNumber; i++)
    {
        BYTE* pTemp = (BYTE*)m_pTImgFrame[i];
        if (pTemp != NULL)
        {
            delete[] pTemp;
            m_pTImgFrame[i] = NULL;
        }
    }
    delete []m_pTImgFrame;
    m_pTImgFrame = NULL;
}

变量声明:

typedef unsigned int        UINT;
typedef struct _TImage
{
    int  w;         
    int  h;         
    int  pitch;     
    int  attrib;    
    unsigned char data[4];  
} TImage;

UINT        m_nFrameNumber;     
UINT*       m_pnFrameDelay;     
TImage**    m_pTImgFrame;

PBITMAPINFOHEADER pbih; 
typedef struct tagBITMAPINFOHEADER{
    DWORD      biSize;
    LONG       biWidth;
    LONG       biHeight;
    WORD       biPlanes;
    WORD       biBitCount;
    DWORD      biCompression;
    DWORD      biSizeImage;
    LONG       biXPelsPerMeter;
    LONG       biYPelsPerMeter;
    DWORD      biClrUsed;
    DWORD      biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

分配:

    m_pTImgFrame = new TImage*[1];
    m_pTImgFrame[0] = (TImage*)new BYTE[sizeof(TImage) - 4 + 4 * width * pbih->biHeight];
    m_pTImgFrame[0]->attrib = imageAttrib8888;
    m_pTImgFrame[0]->w = width;
    m_pTImgFrame[0]->h = pbih->biHeight;
    m_pTImgFrame[0]->pitch = 4 * width;
    LOG(_T("32width=%d, height=%d"), width, pbih->biHeight);
    for(j=pbih->biHeight-1; j>=0; j--)
    {
        int indexDst = (pbih->biHeight-j-1) * width * 4;
        //int indexSrc = j * pbih->biWidth * 4;
        int indexSrc = j * ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8/*bmpInfo.bmWidthBytes*/;
        for(i=0; i< width; i++)
        {
            m_pTImgFrame[0]->data[indexDst++] = lpBits[indexSrc++];
            m_pTImgFrame[0]->data[indexDst++] = lpBits[indexSrc++];
            m_pTImgFrame[0]->data[indexDst++] = lpBits[indexSrc++];
            m_pTImgFrame[0]->data[indexDst++] = 255;
            indexSrc++;
        }
    }

运行该行时代码会崩溃 delete [] pTemp如果m_nFrameNumber为1(我只看到它是1时发生了崩溃,但我不确定);pTemp的每个值的输出都是正确的,为什么会崩溃?

【问题讨论】:

  • How do I ask a good question?。发布代码图像并不好。邮政编码。
  • 如果你删除了一些内存,你肯定已经更新了它,但我在你的代码中看不到任何新的。
  • @RSahu 我发布了代码图像,因为有一个自动窗口,所以变量的值将在运行崩溃行之前显示在上面。对于任何使用 Visual Studio 的人来说,我认为它比纯代码要好得多。
  • 最好有可以复制/粘贴的代码和一个 MCVE
  • 不要发布您的代码图片。 发布实际代码本身。我无法将相关部分剪切并粘贴到答案中。所以是的,我有一个答案,但您需要将代码作为文本发布。另外,请说明您在哪里分配 m_pTImgFrame 以及其中的各个元素。

标签: c++ visual-c++


【解决方案1】:

如果m_nFrameNumberdelete [] pTemp,代码会在运行时崩溃 1

鉴于你刚才所说的分配如下:

m_pTImgFrame = new TImage*[1];

m_pTImgFrame 的唯一有效索引是0,因为您只分配了大小为1 的数组。尝试访问 m_pTImgFrame[1] 是未定义的行为。

其次,您的新操作符需要与您的删除操作符匹配类型和标量。

您分配为字节数组:

m_pTImgFrame[0] = (TImage*)new BYTE[sizeof(TImage) - 4 + 4 * width * pbih->biHeight];

因此,释放元素的正确方法是这样的:

BYTE* allocation = (BYTE*)m_pTImgFrame[0];
delete [] allocaiton;

这是错误的:

    TImage* pTemp = (TImage*)m_pTImgFrame[i];
    if (pTemp != NULL)
    {
        ...
        delete[] pTemp; // deleting as an array of TImage, when it should be deleted as an array of bytes
    }

基于 yoru 代码的不相关切线 - 在调用 delete 之前不需要检查 NULL。一直很安全地说delete NULL。永远都是。

【讨论】:

  • 提前感谢,BYTE* 强制转换用于首先崩溃的原始代码,所以我重写了代码以输出pTemp 的值。 m_nFrameNumber 为 1 不能让 i 为 1,所以我认为 m_pTImgFrame[0] 是安全的。
  • 最后是vs2015项目中使用vc6编译的dll造成的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
相关资源
最近更新 更多