现在在修改之前写的代码,发现其中一个问题,示例代码如下:
//Video.h
class Video
{
public:
Video(int nr, int nc);
~Video();
public:
int* GetVideoData();
private:
int *m_pBuff;
}
//Video.cpp
Video::Video()
{
}
Video::Video(int nr, int nc)
{
m_pBuff = new int[nr * nc]
}
~Video::Video()
{
delete[] m_pBuff;
m_pBuff = nullptr;
}
int* Video::GetVideoData{}
{
return m_pBuff;
}
//测试
void main()
{
int nr = 100;
int nc = 100;
Video *pVideo = nullptr;
if(!pVideo)
{
pVideo = new Video(nr, nc);
}
//为了方便写代码,将pBuff指向Video中的m_pBuff
int *pBuff = nullptr;
if(!pBuff)
{
int *pBuff = pVideo->GetVideoData();
}
for (int i = 0; i < nr * nc; i++)
{
pBuff[i] = i;
}
//释放内存方式1
delete pVideo;
pVideo = nullptr;
delete[] pBuff; //error
pBuff = nullptr;
//--------------------
//释放内存方式2
delete pVideo; //这里为了改错误,不释放pBuff
pVideo = nullptr;
//--------------------
if(!pBuff)
{
/*
虽然释放方式2可以通过,但是忘记了将pBuff设为nullptr,所以这里无法进入
代码只是为了演示用,实际中与这有差别,不必纠结为什么释放内存在这之前
*/
}
}
让两个指针指向同一块内存,我觉得引发的问题有两点:
(1)很容易引发多次释放同一块内存,俗话说,new和delete要成双成对,当程序庞大时,特别麻烦。即使将演示代码中的释放内存方式1改成如下形式,也是没作用的。
//释放内存代码1
if(m_pVideo)
{
delete m_pVideo;
m_pVideo = nullptr;
}
if(pBuff) //这里能进入,虽然pBuff指向的内存释放了,但是其指针并不为nullptr
{
delete[] pBuff; //error
pBuff = nullptr;
}
(2)容易引发野指针,这个真是防不胜防,所以每次delete后都要将指针设为nullptr。但是两个指针指向同一块内存时,这个经常被遗忘!