Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我的程序正在泄漏boost::shared_ptr拥有的资源_C++_Boost_Memory Leaks_Stdmap - Fatal编程技术网

C++ 我的程序正在泄漏boost::shared_ptr拥有的资源

C++ 我的程序正在泄漏boost::shared_ptr拥有的资源,c++,boost,memory-leaks,stdmap,C++,Boost,Memory Leaks,Stdmap,我不明白为什么我的程序会泄漏,也许你能发现它 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

我不明白为什么我的程序会泄漏,也许你能发现它

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;
}
我很想知道我遗漏了什么——所有的StringPtr都在泄漏

更新 关于“StringPtr(newstd::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())的建议,并以这种方式回避了这个问题。

在VS2010
std::vector
实现中存在一个bug,在某些情况下会导致内存泄漏(请参阅)。好吧,它已经在VS2010 SP1中修复,但我不是100%肯定。

我同意詹姆斯的建议:


@弗里法尔:没有;当你有一个std::map m;然后你做一个m.insert(std::make_pair(0,std::string(“Hello World”);,将临时std::字符串(“Hello World”)的副本插入到std::map中詹姆斯·麦克内利斯(James McNellis)

不会回答你的问题(因为我看不出任何问题),但有两点:

typedef std::map  < HWND, std::string >     WindowMap;
typedef WindowMap::value_type               WMapPair;    // In the future it may not be a pair.
                                                         // Or you may change the type of WindowMap
                                                         // Make it so the value is based on the container.
                                                         // Done automatically.

// 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

    // Declare variables at there first usage point.
    // There is no need to clutter the top of the function 
    // With usless variables that may never be used.

    if( ! ::IsWindow( hWnd ) )
        return FALSE;

    int nTextLen = GetWindowTextLength( hWnd );
    if( ! nTextLen )
        return TRUE;

    // Use a vector. Dynamically allocating memory is dangerious and not
    // exception safe (unless you use a smart pointer (or in this case a container))
    std::vector<char>  sWindowText(nTextLen + 1);
    GetWindowTextA( hWnd, &sWindowText[0], nTextLen );

    // No need for shared pointers. Just put the string in the map.
    m_Windows.insert( WMapPair(hWnd, std::string(sWindowText.begin(),
                                                 sWindowText.begin()+ nTextLen)));

    return TRUE;
}
typedef std::mapWindowMap;
typedef WindowMap::value_type WMapPair;//将来它可能不是一对。
//或者您可以更改WindowMap的类型
//使其值基于容器。
//自动完成。
//此回调通过每次添加WMapPair来填充WindowMap(m_Windows)
布尔回调枚举窗口回调(HWND HWND)
{
//将此窗口及其标题文本添加到WindowMap
//在第一个使用点声明变量。
//没有必要把函数的顶部弄得乱七八糟
//使用可能永远不会使用的usless变量。
如果(!::IsWindow(hWnd))
返回FALSE;
int nTextLen=GetWindowTextLength(hWnd);
如果(!nTextLen)
返回TRUE;
//使用向量。动态分配内存是危险的,而不是
//异常安全(除非使用智能指针(或在本例中为容器))
std::矢量sWindowText(nTextLen+1);
GetWindowTextA(hWnd和sWindowText[0],nTextLen);
//不需要共享指针。只需将字符串放在映射中。
m_Windows.insert(WMapPair(hWnd,std::string)(sWindowText.begin(),std::string),
sWindowText.begin()+nTextLen));
返回TRUE;
}

这在风格上是错误的:
StringPtr(新std::string(sWindowText))
。每个新的动态分配对象最初都应该由一个命名的智能指针拥有。更多信息,请阅读。此外,考虑使用<代码> STD::vector ,而不是自己动态地分配数组。不过,我认为这两个问题都不是你具体问题的原因。@freefillr:不;当你有一个
std::map mm.insert(std::make_pair(0,std::string(“helloworld”))
,将临时的
std::string(“Hello World”)
的副本插入到
std::map
中。您确定没有循环引用吗?这就是boost::weak_ptr的用途。您需要调整向量的大小,使其具有足够的大小,然后可以使用
&v[0]
获取指向其初始元素的指针。例如:
std::vectorv(nTextLen+1);GetWindowText(hWnd,&v[0],nTextLen)@freefillr-不,它不能您链接到的页面是针对
运算符new
的,您可以覆盖该运算符,以便为类型分配一些特殊的内存。我的页面是关于
new
的,类似于
newx
。尽管它们都使用了单词
new
,但它们的意思不同。我可以向您保证,
new x
不会返回NULL,它会引发异常。感谢提醒,我没有意识到这一点!我确实安装了VS2010 SP1,我的问题似乎是地图而不是向量。没有任何东西阻止
map
在内部使用
vector
。我可以确认这在SP1中得到了修复。是的,我采用了这种方法(如前面提到的James建议)
typedef std::map  < HWND, std::string >     WindowMap;
typedef WindowMap::value_type               WMapPair;    // In the future it may not be a pair.
                                                         // Or you may change the type of WindowMap
                                                         // Make it so the value is based on the container.
                                                         // Done automatically.

// 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

    // Declare variables at there first usage point.
    // There is no need to clutter the top of the function 
    // With usless variables that may never be used.

    if( ! ::IsWindow( hWnd ) )
        return FALSE;

    int nTextLen = GetWindowTextLength( hWnd );
    if( ! nTextLen )
        return TRUE;

    // Use a vector. Dynamically allocating memory is dangerious and not
    // exception safe (unless you use a smart pointer (or in this case a container))
    std::vector<char>  sWindowText(nTextLen + 1);
    GetWindowTextA( hWnd, &sWindowText[0], nTextLen );

    // No need for shared pointers. Just put the string in the map.
    m_Windows.insert( WMapPair(hWnd, std::string(sWindowText.begin(),
                                                 sWindowText.begin()+ nTextLen)));

    return TRUE;
}