奇怪的内存泄露!!!

wangsiyuanoo 2009-12-14 10:41:54
typedef struct tag_GameInfo 
{
string m_strGameName;

void clear()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}

tag_GameInfo()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}

~tag_GameInfo()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}
}GAMEINFO, *LPGAMEINFO;

string GetString( char * strIniPath, const char * strFront, const char * strBack )
{
string strString = "";

string strCurPath = GetCurPath();
char strTm[MAX_PATH] = {0};
sprintf_s(strTm, "%s\\%s", strCurPath.c_str(), strIniPath);
strIniPath = strTm;
CString strTemp = "";
GetPrivateProfileString( strFront, strBack, "", strTemp.GetBuffer(MAX_PATH), MAX_PATH, strIniPath);

return strString = strTemp.GetBuffer(0);
}

void CGameTreeView::GetAllGameInfo()
{
int iGameCount = GetInt("attrres\\GameInfo.ini", "info", "count");
for ( int i = 0; i < iGameCount; i++ )
{
char strTm[MAX_PATH] = {0};
sprintf_s(strTm, "game%d", i);

LPGAMEINFO pGameInfo = new GAMEINFO;

//string strGameName = GetString("attrres\\GameInfo.ini", strTm, "name"); //不会内存泄露
pGameInfo->m_strGameName = GetString("attrres\\GameInfo.ini", strTm, "name"); //造成16 bytes long的内存泄露!!!

m_mapGameInfo[pGameInfo->m_uiGameID] = pGameInfo;
}
}

CGameTreeView::~CGameTreeView()
{
map<UINT, LPGAMEINFO>:: iterator iter_GameInfo = m_mapGameInfo.begin();
for (; iter_GameInfo != m_mapGameInfo.end(); iter_GameInfo++)
{
if ( NULL != iter_GameInfo->second )
{
delete iter_GameInfo->second;
iter_GameInfo->second = NULL;
}

}
m_mapGameInfo.clear();
}



都是给一个string赋值,为什么一个会内存泄露,而一个不会呢?
...全文
321 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
Saingel 2009-12-15
  • 打赏
  • 举报
回复
不要用ZeroMemory去清空代有私有buf类型参数的结构体,
string如果有内容,被你清一下私有buf就会指空,原有的数据就不会释放
maquan 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 taodm 的回复:]
        ZeroMemory(this, sizeof(tag_GameInfo));
是一个非常有创意的行为,它足以让你重修最基础教材。
[/Quote]
啥意思?
firmbird 2009-12-15
  • 打赏
  • 举报
回复
没有说调用了GetBuffer之后一定要调用ReleaseBuffer啊,
MS只是强调在使用GetBuffer返回的指针上进行了修改,再使用其他方法的话必须要调用ReleaseBuffer.
taodm 2009-12-15
  • 打赏
  • 举报
回复
ZeroMemory(this, sizeof(tag_GameInfo));
是一个非常有创意的行为,它足以让你重修最基础教材。
wangsiyuanoo 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 xwb2766 的回复:]
LPGAMEINFO pGameInfo = new GAMEINFO;
       
        //string strGameName = GetString("attrres\\GameInfo.ini", strTm, "name");        //不会内存泄露
        pGameInfo->m_strGameName = GetString("attrres\\GameInfo.ini", strTm, "name");    //造成16 bytes long的内存泄露!!!


pGameInfo 是new出来的,也就是说它是在堆heap中申请的空间,你用完后没有释放,自然就内存泄漏
而strGameName 是一个在初始化时赋的值是一个常量区的地址,它存储的是全局常量区的字符串,没有额外在heap中申请空间,自然不存在内存泄漏的问题。
eg:
int *pi = new int;
int i;之间的区别一样
[/Quote]
看清楚,我在最后的析构里有释放pGameInfo!
qlong_008 2009-12-15
  • 打赏
  • 举报
回复
给分啊
taodm 2009-12-15
  • 打赏
  • 举报
回复
23楼的创意也很好。
qlong_008 2009-12-15
  • 打赏
  • 举报
回复
typedef struct tag_GameInfo
{
string m_strGameName;

void clear()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}

tag_GameInfo()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}

~tag_GameInfo()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}
}GAMEINFO, *LPGAMEINFO;
////////////////////////////
~tag_GameInfo()
{
ZeroMemory(this, sizeof(tag_GameInfo));
}
这个有问题了,,,,
呵呵
string m_strGameName的内存有泄露,,,没有清掉,,
~tag_GameInfo()
{
strGameName.clear();
ZeroMemory(this, sizeof(tag_GameInfo));
}
这样应该就没有问题了


llaaddoo 2009-12-15
  • 打赏
  • 举报
回复
ZeroMemory(this, sizeof(tag_GameInfo));
直接将一个对象内存清0了~~~
wangsiyuanoo 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 macrojj 的回复:]
不是。
[/Quote]
那到底怎么让他不内存泄露呢?
macrojj 2009-12-14
  • 打赏
  • 举报
回复
不是。
wangsiyuanoo 2009-12-14
  • 打赏
  • 举报
回复
也就是说
我可以忽略掉这个内存泄露了?
dukong123 2009-12-14
  • 打赏
  • 举报
回复
string strGameName = GetString("attrres\\GameInfo.ini", strTm, "name");
此时是局部对象,除了生存期后,自动析构
wangsiyuanoo 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 demon__hunter 的回复:]
ms不少内存泄漏检测工具把 分配但未被使用的内存 当做了内存泄露~~~~~
对于这些工具来说 STL经常出现内存泄露~~~~
[/Quote]
那对于这种“内存泄露”到底是不是内存泄露呢?!
wangsiyuanoo 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 taodm 的回复:]
因为你测量内存泄漏的工具太垃圾,误报率太高。
[/Quote]
不是吧。。。
就是VS 2005的output报出的内存泄露错误提示啊...
难道不是我的错,是他的错...
机智的呆呆 2009-12-14
  • 打赏
  • 举报
回复
ms不少内存泄漏检测工具把 分配但未被使用的内存 当做了内存泄露~~~~~
对于这些工具来说 STL经常出现内存泄露~~~~
taodm 2009-12-14
  • 打赏
  • 举报
回复
因为你测量内存泄漏的工具太垃圾,误报率太高。
xwb2766 2009-12-14
  • 打赏
  • 举报
回复
LPGAMEINFO pGameInfo = new GAMEINFO;

//string strGameName = GetString("attrres\\GameInfo.ini", strTm, "name"); //不会内存泄露
pGameInfo->m_strGameName = GetString("attrres\\GameInfo.ini", strTm, "name"); //造成16 bytes long的内存泄露!!!


pGameInfo 是new出来的,也就是说它是在堆heap中申请的空间,你用完后没有释放,自然就内存泄漏
而strGameName 是一个在初始化时赋的值是一个常量区的地址,它存储的是全局常量区的字符串,没有额外在heap中申请空间,自然不存在内存泄漏的问题。
eg:
int *pi = new int;
int i;之间的区别一样
老邓 2009-12-14
  • 打赏
  • 举报
回复
嗯,换下顺序试试。

GetPrivateProfileString( strFront, strBack, "", strTemp.GetBuffer(MAX_PATH), MAX_PATH, strIniPath);
strTemp.ReleaseBuffer();
strString = strTemp;
wangsiyuanoo 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 loaden 的回复:]
改成这样就没泄露了:
C/C++ codeGetPrivateProfileString( strFront, strBack,"", strTemp.GetBuffer(MAX_PATH), MAX_PATH, strIniPath);
strString= strTemp;
strTemp.ReleaseBuffer();return strString;
[/Quote]
不对啊。。。。
我改成:
string GetString( char * strIniPath, const char * strFront, const char * strBack )
{
string strString = "";

string strCurPath = GetCurPath();
char strTm[MAX_PATH] = {0};
sprintf_s(strTm, "%s\\%s", strCurPath.c_str(), strIniPath);
strIniPath = strTm;
CString strTemp = "";
GetPrivateProfileString( strFront, strBack, "", strTemp.GetBuffer(MAX_PATH), MAX_PATH, strIniPath);
strString = strTemp;
strTemp.ReleaseBuffer();

return strString;
}

还是会泄露16位的长度。。。。
加载更多回复(5)

64,637

社区成员

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

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