我不知道为什么我的程序会出现内存泄漏,也许你能发现问题所在。
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都在泄漏。
更新 关于"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())的建议,并以此方式规避了这个问题。
StringPtr(new std::string(sWindowText))
。每个新动态分配的对象都应该最初由一个具有名称的智能指针拥有。要了解更多信息,请阅读Boost shared_ptr 最佳实践。此外,考虑使用std::vector<char>
代替自己动态分配数组。不过我不认为这两者是您特定问题的原因。 - James McNellisstd::map<int, std::string> m;
并且执行m.insert(std::make_pair(0, std::string("Hello World")));
时,一个临时的std::string("Hello World")
的副本会被插入到std::map
中。 - James McNellis&v[0]
获取指向其初始元素的指针。例如:std::vector<TCHAR> v(nTextLen + 1); GetWindowText(hWnd, &v[0], nTextLen);
- James McNellisoperator new
的,它是一个你可以重载以为类型进行一些特殊内存分配的运算符。我的页面是关于像new x
这样的语句中的new
。尽管它们都使用单词new
,但它们的意思不同。我可以向你保证,new x
不会返回NULL,它会抛出异常。 - Bo Persson