使用delete[]删除指针时崩溃

Crash when using delete [] to delete a pointer

本文关键字:指针 崩溃 删除 delete 使用      更新时间:2023-10-16

我用来输出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,%dn"), 
                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;
}

源代码仍然崩溃

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++;
        }
    }

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

如果m_nFrameNumber 1 ,则运行行delete [] pTemp时代码将崩溃

考虑到你刚才所说的,分配如下:

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总是很安全的。永远都是。