我的程序因 boost::shared_ptr 拥有的资源而泄漏
我不明白为什么我的程序会泄漏,也许你可以发现它。
typedef boost::shared_ptr < std::string > StringPtr;
typedef std::pair < HWND, StringPtr > WMapPair;
typedef std::map < HWND, StringPtr > WindowMap;
// this callback populates the WindowMap (m_Windows) by adding a WMapPair each time
BOOL CALLBACK EnumWindowsCallback( HWND hWnd )
{
// adds this window to the WindowMap, along with its title text
BOOL bRetVal = FALSE;
int nTextLen = 0;
char* sWindowText = NULL;
if( ! ::IsWindow( hWnd ) )
return FALSE;
nTextLen = GetWindowTextLength( hWnd );
if( ! nTextLen )
return TRUE;
sWindowText = new char[nTextLen + 1];
if( sWindowText )
{
GetWindowTextA( hWnd, sWindowText, nTextLen );
m_Windows.insert( WMapPair(hWnd, StringPtr(new std::string(sWindowText))) );
delete [] sWindowText;
sWindowText = NULL;
bRetVal = TRUE;
}
return bRetVal;
}
我的类包含此 WindowMap 填充工作正常,但拆卸似乎无法正常工作。类析构函数调用此函数来清除映射 - 这应该释放shared_ptr,从而删除它们,对吧? :)
void EraseList()
{
m_Windows.clear();
}
我很想知道我错过了什么 - 所有 StringPtr 都泄漏了。
更新 RE“StringPtr(new std::string(sWindowText)))”的评论在风格上是错误的,我做了建议的更改,如下所示,但是内存泄漏仍然存在。
BOOL CALLBACK EnumWindowsCallback( HWND hWnd )
{
// adds this window to the WindowMap, along with its title text
BOOL bRetVal = FALSE;
int nTextLen = 0;
char* sWindowText = NULL;
StringPtr strPtr;
if( ! ::IsWindow( hWnd ) )
return FALSE;
nTextLen = GetWindowTextLength( hWnd );
if( ! nTextLen )
return TRUE;
sWindowText = new char[nTextLen + 1];
if( sWindowText )
{
GetWindowTextA( hWnd, sWindowText, nTextLen );
strPtr = StringPtr(new std::string(sWindowText));
m_Windows.insert( WMapPair(hWnd, strPtr) );
delete [] sWindowText;
sWindowText = NULL;
bRetVal = TRUE;
}
return bRetVal;
}
结论 我已经接受了放弃 StringPtr 并使用 make_pair(hWnd, std::string()) 的建议,并以这种方式回避了这个问题。
I can't see why my program is leaking, maybe you can spot it.
typedef boost::shared_ptr < std::string > StringPtr;
typedef std::pair < HWND, StringPtr > WMapPair;
typedef std::map < HWND, StringPtr > WindowMap;
// this callback populates the WindowMap (m_Windows) by adding a WMapPair each time
BOOL CALLBACK EnumWindowsCallback( HWND hWnd )
{
// adds this window to the WindowMap, along with its title text
BOOL bRetVal = FALSE;
int nTextLen = 0;
char* sWindowText = NULL;
if( ! ::IsWindow( hWnd ) )
return FALSE;
nTextLen = GetWindowTextLength( hWnd );
if( ! nTextLen )
return TRUE;
sWindowText = new char[nTextLen + 1];
if( sWindowText )
{
GetWindowTextA( hWnd, sWindowText, nTextLen );
m_Windows.insert( WMapPair(hWnd, StringPtr(new std::string(sWindowText))) );
delete [] sWindowText;
sWindowText = NULL;
bRetVal = TRUE;
}
return bRetVal;
}
My class contains this WindowMap population works correctly, but teardown doesn't seem to be working correctly. The class destructor calls this function to clear the map - which should release the shared_ptr's, thereby deleting them, right? :)
void EraseList()
{
m_Windows.clear();
}
I'd love to know what I'm missing - all the StringPtr's are leaking.
UPDATE
RE the comment that the "StringPtr(new std::string(sWindowText)))" was stylistically wrong, I made the suggested change, as below, but, the memory leak is still there.
BOOL CALLBACK EnumWindowsCallback( HWND hWnd )
{
// adds this window to the WindowMap, along with its title text
BOOL bRetVal = FALSE;
int nTextLen = 0;
char* sWindowText = NULL;
StringPtr strPtr;
if( ! ::IsWindow( hWnd ) )
return FALSE;
nTextLen = GetWindowTextLength( hWnd );
if( ! nTextLen )
return TRUE;
sWindowText = new char[nTextLen + 1];
if( sWindowText )
{
GetWindowTextA( hWnd, sWindowText, nTextLen );
strPtr = StringPtr(new std::string(sWindowText));
m_Windows.insert( WMapPair(hWnd, strPtr) );
delete [] sWindowText;
sWindowText = NULL;
bRetVal = TRUE;
}
return bRetVal;
}
Conclusion
I've gone with the suggestion of ditching StringPtr and using make_pair(hWnd, std::string()) and have sidestepped the issue that way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
VS2010
std::vector<>
实现中存在(是?)一个错误,导致在某些情况下内存泄漏(请参阅此处)。 AFAIK,它已在 VS2010 SP1 中修复,但我不是 100% 肯定。There was (is?) a bug in VS2010
std::vector<>
implementation causing memory to leak under certain circumstances (see here). AFAIK, it has been fixed in VS2010 SP1, but I'm not 100% positive.不会回答你的问题(因为我看不到任何问题),但有几点:
Not going to answer your question (as I can;t see any problems) but a couple of points:
我接受了詹姆斯的建议:
@freefallr:不;当你有一个 std::map m; 时然后执行 m.insert(std::make_pair(0, std::string("Hello World"))); ,将临时 std::string("Hello World") 的副本插入到 std 中: :地图。 ——詹姆斯·麦克内利斯
I've gone with James' suggestion:
@freefallr: No; when you have a std::map m; and you do a m.insert(std::make_pair(0, std::string("Hello World")));, a copy of the temporary std::string("Hello World") is inserted into the std::map. – James McNellis