C++ 集装箱泄漏

C++ 集装箱泄漏,c++,windows,winapi,stl,C++,Windows,Winapi,Stl,我使用一个向量容器来保存一个对象的实例,该对象包含3个int和2个std::strings,这是在堆栈上创建的,并由另一个类中的函数填充,但通过deleaker运行应用程序表明,对象中的std::strings都泄漏了。代码如下: // Populator function: void PopulatorClass::populate(std::vector<MyClass>& list) { // m_MainList contains a list of poin

我使用一个向量容器来保存一个对象的实例,该对象包含3个int和2个
std::string
s,这是在堆栈上创建的,并由另一个类中的函数填充,但通过deleaker运行应用程序表明,对象中的
std::string
s都泄漏了。代码如下:

// Populator function:
void PopulatorClass::populate(std::vector<MyClass>& list) {
    // m_MainList contains a list of pointers to the master objects
    for( std::vector<MyClass*>::iterator it = m_MainList.begin(); it != m_MainList.end(); it++ ) {
        list.push_back(**it);
    }
}

// Class definition
class MyClass {
private:
    std::string m_Name;
    std::string m_Description;
    int m_nType;
    int m_nCategory;
    int m_nSubCategory;
};

// Code causing the problem:
std::vector<MyClass> list;
PopulatorClass.populate(list);
//填充器函数:
void PopulatorClass::populate(标准::向量和列表){
//m_MainList包含指向主对象的指针列表
对于(std::vector::iterator it=m_MainList.begin();it!=m_MainList.end();it++){
列表。推回(**it);
}
}
//类定义
类MyClass{
私人:
std::字符串m_名称;
std::字符串m_描述;
国际货币基金组织;
国际货币联盟分类;
国际m_nSubCategory;
};
//导致问题的代码:
std::向量表;
PopulatorClass.populate(列表);
当通过deleaker运行时,泄漏的内存位于
std::string
类的分配器中

我正在使用VisualStudio2010(CRT)

在展开堆栈并删除
向量时,是否需要执行任何特殊操作来正确删除
字符串

谢谢,
J

可能是或类似于此。

可能是或类似于此。

每当您在STL实现中遇到问题时,执行一些奇怪或错误的操作,例如内存泄漏,请尝试以下操作:

  • 重现您尝试实现的最基本示例。如果它运行时没有泄漏,则问题在于您填充数据的方式这是最可能的问题来源(我指的是您自己的代码)。
未针对您的特定问题进行简单的即时测试示例:

#include <string>
#include <sstream>


// Class definition
struct MyClass  { // struct for convenience
    std::string m_Name;
    std::string m_Description;
    int m_nType;
    int m_nCategory;
    int m_nSubCategory;
};


// Prototype of populator function:
void populate(std::vector<MyClass>& list)
{
    const int MAX_TYPE_IDX = 4;
    const int MAX_CATEGORY_IDX = 8;
    const int MAX_SUB_CATEGORY_IDX = 6;

    for( int type_idx = 0; type_idx < MAX_TYPE_IDX ; ++type_idx)
        for( int category_idx = 0; category_idx < MAX_CATEGORY_IDX ; ++category_idx)
             for( int sub_category_idx = 0; sub_category_idx < MAX_SUB_CATEGORY_IDX ; ++sub_category_idx)
             {
                   std::stringstream name_stream;
                   name_stream << "object_" << type_idx << "_" << category_idx << "_" << sub_category_idx ;
                   std::stringstream desc_stream;
                   desc_stream << "This is an object of the type N°" << type_idx << ".\n";
                   desc_stream << "It is of category N°" << category_idx << ",\n";
                   desc_stream << "and of sub-category N°" << category_idx << "!\n";

                   MyClass object;
                   object.m_Name = name_stream.str();
                   object.m_Description = desc_stream.str();
                   object.m_nType = type_idx;
                   m_nCategory = 
                   m_nSubCategory = 
                   list.push_back( object );
             }
}


int main()
{
    // Code causing the problem:
    std::vector<MyClass> list;
    populate(list);

    // memory leak check?
    return 0;
 }
#包括
#包括
//类定义
struct MyClass{//struct以方便起见
std::字符串m_名称;
std::字符串m_描述;
国际货币基金组织;
国际货币联盟分类;
国际m_nSubCategory;
};
//populator函数的原型:
无效填充(标准::向量和列表)
{
常量int MAX_TYPE_IDX=4;
const int MAX_CATEGORY_IDX=8;
const int MAX_SUB_CATEGORY_IDX=6;
对于(int type_idx=0;type_idxname_stream每当您在STL实现中遇到一些奇怪或错误(如内存泄漏)时,请尝试以下操作:

  • 重现您尝试实现的最基本示例。如果它运行时没有泄漏,则问题在于您填充数据的方式。这是最可能的问题来源(我指的是您自己的代码)。
未针对您的特定问题进行简单的即时测试示例:

#include <string>
#include <sstream>


// Class definition
struct MyClass  { // struct for convenience
    std::string m_Name;
    std::string m_Description;
    int m_nType;
    int m_nCategory;
    int m_nSubCategory;
};


// Prototype of populator function:
void populate(std::vector<MyClass>& list)
{
    const int MAX_TYPE_IDX = 4;
    const int MAX_CATEGORY_IDX = 8;
    const int MAX_SUB_CATEGORY_IDX = 6;

    for( int type_idx = 0; type_idx < MAX_TYPE_IDX ; ++type_idx)
        for( int category_idx = 0; category_idx < MAX_CATEGORY_IDX ; ++category_idx)
             for( int sub_category_idx = 0; sub_category_idx < MAX_SUB_CATEGORY_IDX ; ++sub_category_idx)
             {
                   std::stringstream name_stream;
                   name_stream << "object_" << type_idx << "_" << category_idx << "_" << sub_category_idx ;
                   std::stringstream desc_stream;
                   desc_stream << "This is an object of the type N°" << type_idx << ".\n";
                   desc_stream << "It is of category N°" << category_idx << ",\n";
                   desc_stream << "and of sub-category N°" << category_idx << "!\n";

                   MyClass object;
                   object.m_Name = name_stream.str();
                   object.m_Description = desc_stream.str();
                   object.m_nType = type_idx;
                   m_nCategory = 
                   m_nSubCategory = 
                   list.push_back( object );
             }
}


int main()
{
    // Code causing the problem:
    std::vector<MyClass> list;
    populate(list);

    // memory leak check?
    return 0;
 }
#包括
#包括
//类定义
struct MyClass{//struct以方便起见
std::字符串m_名称;
std::字符串m_描述;
国际货币基金组织;
国际货币联盟分类;
国际m_nSubCategory;
};
//populator函数的原型:
无效填充(标准::向量和列表)
{
常量int MAX_TYPE_IDX=4;
const int MAX_CATEGORY_IDX=8;
const int MAX_SUB_CATEGORY_IDX=6;
对于(int type_idx=0;type_idxname_stream可能与Alexey的链接存在相同的根问题。发布的版本已破坏基本_string的移动代码。MS放弃了我们VC10用户,因此您必须自己修复它。在xstring文件中,您有以下内容:

_Myt& assign(_Myt&& _Right)
    {        // assign by moving _Right
    if (this == &_Right)
        ;
    else if (get_allocator() != _Right.get_allocator()
        && this->_BUF_SIZE <= _Right._Myres)
        *this = _Right;
    else
        {        // not same, clear this and steal from _Right
        _Tidy(true);
        if (_Right._Myres < this->_BUF_SIZE)
            _Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
                _Right._Mysize + 1);
        else
            {        // copy pointer
            this->_Bx._Ptr = _Right._Bx._Ptr;
            _Right._Bx._Ptr = 0;
            }
        this->_Mysize = _Right._Mysize;
        this->_Myres = _Right._Myres;

        _Right._Mysize = 0;
        _Right._Myres = 0;
        }
    return (*this);
    }
\u Myt&assign(\u Myt&&u Right)
{//通过向右移动\来分配
如果(此==&_右)
;
else if(get_allocator()!=_Right.get_allocator()
&&这个->_BUF_大小_BUF_大小)
_特征::移动(这个->,
_右。_Mysize+1);
其他的
{//复制指针
这个->\u Bx.\u Ptr=\u Right.\u Bx.\u Ptr;
_右。_Bx。_Ptr=0;
}
这个->\u Mysize=\u Right.\u Mysize;
这个->\u Myres=\u Right.\u Myres;
_右。_Mysize=0;
_右。_Myres=0;
}
返回(*本条);
}
注意最后一点

_右。_Myres=0

这种情况只有在最后一种情况下才会发生,因为在短期内,最好让右翼独处


由于容量设置为0而不是15,其他代码将在函数Grow()中执行意外分支当您分配另一个小字符串,并将分配一个内存块,以便用即时字符串内容踩踏指针时。

可能与Alexey的链接存在相同的根问题。附带的版本已破坏基本字符串的移动代码。MS放弃了我们VC10用户,因此您必须自己修复它。在xstring文件中,您有以下内容:

_Myt& assign(_Myt&& _Right)
    {        // assign by moving _Right
    if (this == &_Right)
        ;
    else if (get_allocator() != _Right.get_allocator()
        && this->_BUF_SIZE <= _Right._Myres)
        *this = _Right;
    else
        {        // not same, clear this and steal from _Right
        _Tidy(true);
        if (_Right._Myres < this->_BUF_SIZE)
            _Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
                _Right._Mysize + 1);
        else
            {        // copy pointer
            this->_Bx._Ptr = _Right._Bx._Ptr;
            _Right._Bx._Ptr = 0;
            }
        this->_Mysize = _Right._Mysize;
        this->_Myres = _Right._Myres;

        _Right._Mysize = 0;
        _Right._Myres = 0;
        }
    return (*this);
    }
\u Myt&assign(\u Myt&&u Right)
{//通过向右移动\来分配
如果(此==&_右)
;
else if(get_allocator()!=_Right.get_allocator()
&&这个->_BUF_大小_BUF_大小)
_特征::移动(这个->,
_右。_Mysize+1);
其他的
{//复制指针
这个->\u Bx.\u Ptr=\u Right.\u Bx.\u Ptr;
_右。_Bx。_Ptr=0;
}
这个->\u Mysize=\u Right.\u Mysize;
这个->\u Myres=\u Right.\u Myres;
_右。_Mysize=0;
_右。_Myres=0;
}
返回(*本条);
}
注意最后一点

_右。_Myres=0

这种情况只有在最后一种情况下才会发生,因为在短期内,最好让右翼独处

由于容量设置为0而不是15,其他代码将接收非预期的分支