高手们,这个函数会内存泄露,要怎么改?

fyz2841585 2010-11-15 05:28:40
void CImageW::GetDTImage(CString strPath)
{
CReadD readDicom;
m_pImage = readDicom.LocalImageData(strPath); readDicom.~CReadDicom();
}


CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;
......................
......................
return pImage;//内存泄露
}
该如何改写这两个函数才不会有内存泄漏。。。
...全文
213 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
fyz2841585 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 kevin_perkins 的回复:]
是这样,CImageW需要有一个数组,保存所有在堆上创建的图片。
比如vector<CxImage*> vImage;
CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;
vImage.push_back(pImage);
return pImage;//内存泄露
……
[/Quote]


这个方法很好,因为我这里有个for循环调用:
CImageW image;
for(;;)
{
image.GetDTImage(m_strPath);//这里有多少张图片就运行多少次
}
........
........
void CImageW::GetDTImage(CString strPath)
{
CReadDicom readDicom;
m_pImage = readDicom.LocalImageData(strPath); readDicom.~CReadDicom();
}


CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;
......................
......................
return pImage;//内存泄露
}
fyz2841585 2010-11-15
  • 打赏
  • 举报
回复
这么多高手发言,无B荣幸,见者有分
heguodong 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gules 的回复:]
return pImage;//内存泄露
-------------------------------------
严格来讲,这不叫内存泄漏,毕竟指向该内存的指针是“可取得的”(如果没进行delete释放,那是程序员的责任);严格意义的内存泄漏是指该内存的所有指针“玩丢了”!
[/Quote]
你这个可以保证自己写一小段代码的时候能作到小心删除返回的指针,但是不能保证人人都注意到
可靠的方式是写健壮的代码
zshtiger2414 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fyz2841585 的回复:]
是上面那个函数调用了下面的那个函数。。。。
[/Quote]

++
科技完美生活 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gules 的回复:]
return pImage;//内存泄露
-------------------------------------
严格来讲,这不叫内存泄漏,毕竟指向该内存的指针是“可取得的”(如果没进行delete释放,那是程序员的责任);严格意义的内存泄漏是指该内存的所有指针“玩丢了”!
[/Quote]

同意
heguodong 2010-11-15
  • 打赏
  • 举报
回复
stl智能指针不具备值语义,无法和容器协作
老邓 2010-11-15
  • 打赏
  • 举报
回复
使用智能指针std::shared_ptr,改成:

std::shared_ptr<CxImage*> CReadDicom::LocalImageData(CString inPath)
{
...
heguodong 2010-11-15
  • 打赏
  • 举报
回复
使用handler技术

class UnitRuntimeInfomation
{
//来自实体模型的字段
//READONLY_PROPERTY(private,int,ID)
READONLY_PROPERTY(private,QString,ClassName)
READONLY_PROPERTY(private,QString,Name)
READONLY_PROPERTY(private,QString,Comment)
//来自单元实体的字段
READONLY_PROPERTY(private,int,PlatformID)
READONLY_PROPERTY(private,QString,PlatformName)
READONLY_PROPERTY(private,double,DamageDegree)
READONLY_PROPERTY(private,double,PriTargetX )
READONLY_PROPERTY(private,double,PriTargetY )
READONLY_PROPERTY(private,QString,Script)
READONLY_PROPERTY(private,UnitRuntimeItem,GraphItem)

friend class UnitRuntimeInfomationHandler;
int useCount;
UnitRuntimeInfomation(const DataAccess::UnitEntity::DataRow& _unit):GraphItem(_unit)
{
ClassName=_unit.GetClassName();
Name=_unit.GetName();
Comment=_unit.GetComment();
PlatformID=_unit.GetPlatformID();
PlatformName=_unit.GetPlatformName();
DamageDegree=_unit.GetDamageDegree();
PriTargetX=_unit.GetPriTargetX();
PriTargetY=_unit.GetPriTargetY();
Script=_unit.GetScript();
}
~UnitRuntimeInfomation(){}
UnitRuntimeInfomation& operator=(const UnitRuntimeInfomation& h);
};
class UnitRuntimeInfomationHandler
{
UnitRuntimeInfomation *p;
public:
UnitRuntimeInfomationHandler():p(0){}
UnitRuntimeInfomationHandler(const DataAccess::UnitEntity::DataRow& _unit)
{
p=new UnitRuntimeInfomation(_unit);
p->useCount=1;
}
UnitRuntimeInfomationHandler(const UnitRuntimeInfomationHandler& handler ):p(handler.p){++p->useCount;}
~UnitRuntimeInfomationHandler()
{
if(p==0)return;
if(--p->useCount==0)
delete p;
}
UnitRuntimeInfomationHandler& operator=(const UnitRuntimeInfomationHandler& h)
{
++h.p->useCount;
if(--p->useCount==0)
delete p;
p=h.p;
return *this;
}

const QString GetName() const
{
return p->GetName();
}
};

返回UnitRuntimeInfomationHandler,而不是infmation*,由handler的析构去处理infmation*,注意不要new ***Handler,***handler设计出来是值语义的
sc_valentine21 2010-11-15
  • 打赏
  • 举报
回复
只有delete了m_pImage,这不存在泄漏。
cheng_fengming 2010-11-15
  • 打赏
  • 举报
回复
这一块好像确实不算内存泄露,但是中间变量pImage返回之后好像没有做什么处理感觉有点不爽
我就想m_pImage成员变量也是CxImage*类型吧,可不可以不要这个中间变量了?设计如下:
void CImageW::GetDTImage(CString strPath)
{
CReadD readDicom;
readDicom.LocalImageData(strPath,m_pImage); //在析构函数中释放m_pImage的资源
}
//可以将返回值设置为BOOL类型,表示执行是否成功
void CReadDicom::LocalImageData(CString inPath,CxImage * pImage)//这样也可以实现改变吧
{
... //do something
}
天外来客-007 2010-11-15
  • 打赏
  • 举报
回复
CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;//调用时 这里new没有析构
......................
......................
return pImage;//内存泄露
}

libinfei8848 2010-11-15
  • 打赏
  • 举报
回复
第一:
CImageW类的析构函数来处理成员变量m_pImage的析构

第二:

void CImageW::GetDTImage(CString strPath)
{
CReadD readDicom;
//delete掉以前的m_pImage
if(m_pImage != NULL)
{
delete m_pImage;
}
m_pImage = readDicom.LocalImageData(strPath); readDicom.~CReadDicom();
}
Kevin_Perkins 2010-11-15
  • 打赏
  • 举报
回复
是这样,CImageW需要有一个数组,保存所有在堆上创建的图片。
比如vector<CxImage*> vImage;
CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;
vImage.push_back(pImage);
return pImage;//内存泄露
}
添加一个函数void ReleaseIamge(void);
void CImageWReleaseIamge(void)
{
for (UINT nIndex = 0; nIndex < vImage.size(); nIndex++)
{
delete vImage[nIndex];
}
vImage.clear();
}
在类的析构函数或其他适当的时候调用,释放所有堆内存即可。
qq120848369 2010-11-15
  • 打赏
  • 举报
回复
void CImageW::GetDTImage(CString strPath)
{
CReadD readDicom;
m_pImage = readDicom.LocalImageData(strPath);
//没必要,自动析构了 readDicom.~CReadDicom();
//既然你开辟了m_pImage只是在当前函数里做一些操作,那用完就delete;
m_pImage->dosth();
delete m_pImage;
//注意,不要使用::operator delete,这个只释放内存不析构的,要使用delete;
}


CxImage* CReadDicom::LocalImageData(CString inPath)
{
CxImage * pImage = new CxImage;
......................
......................
return pImage;//这里返回即可,由上边的函数析构.
}
fyz2841585 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dingshaofengbinbin 的回复:]
delete不就行了吗!!!
[/Quote]
m_pImage不可以删除,还要在别的地方调用哦!
gules 2010-11-15
  • 打赏
  • 举报
回复
return pImage;//内存泄露
-------------------------------------
严格来讲,这不叫内存泄漏,毕竟指向该内存的指针是“可取得的”(如果没进行delete释放,那是程序员的责任);严格意义的内存泄漏是指该内存的所有指针“玩丢了”!
fyz2841585 2010-11-15
  • 打赏
  • 举报
回复
是上面那个函数调用了下面的那个函数。。。。
pengzhixi 2010-11-15
  • 打赏
  • 举报
回复
m_pImage = readDicom.LocalImageData(strPath); readDicom.~CReadDicom();
::operator delete(m_pImage);//这样加上试试吧
dingshaofengbinbin 2010-11-15
  • 打赏
  • 举报
回复
delete不就行了吗!!!

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧