分配包含stl向量的struct时内存泄漏

时间:2015-04-16 14:04:17

标签: c++ vector struct memory-leaks stl

我想为包含std::vector的结构分配内存。分配完成后,我会push_back一些数据。 毕竟,我需要销毁我分配的结构。我想知道如何在没有内存损坏的情况下完成它。

这是我的代码:

typedef struct my_struct_t{

    int a, b;
    vector<unsigned> vec;

}
} MYSTRUCT;


int main(int argc, const char * argv[])
{

    MYSTRUCT* ptr_s =  new MYSTRUCT;

    for(int i = 0 ; i < 100 ; i++){
        ptr_s->vec.push_back(i);
    }
    ptr_s->vec.clear();
    delete ptr_s;

    return 0;
}

我尝试使用clear因为它应该调用析构函数。但是在valgrind我的代码之后,仍然有一些块可以访问。我还尝试使用此解除分配矢量:

vector<unsigned>().swap(ptr_s.vec)

但没有成功。

输出`valgrind':

==52635== HEAP SUMMARY:
==52635==     in use at exit: 10,360 bytes in 5 blocks
==52635==   total heap usage: 147 allocs, 142 frees, 25,198 bytes allocated
==52635== 
==52635== LEAK SUMMARY:
==52635==    definitely lost: 0 bytes in 0 blocks
==52635==    indirectly lost: 0 bytes in 0 blocks
==52635==      possibly lost: 0 bytes in 0 blocks
==52635==    still reachable: 10,360 bytes in 5 blocks
==52635==         suppressed: 0 bytes in 0 blocks
==52635== Reachable blocks (those to which a pointer was found) are not shown.
==52635== To see them, rerun with: --leak-check=full --show-leak-kinds=all

提前谢谢大家。

更新

我注意到我的应用程序中的内存损坏源是在其他地方。所以我添加了更新。这是新代码:

MYSTRUCT* ptr_s1 =  new MYSTRUCT;
MYSTRUCT* ptr_s2 =  new MYSTRUCT;

for(int i = 0 ; i < 100 ; i++){
    ptr_s1->vec.push_back(i);
}


memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));

delete ptr_s1;
delete ptr_s2;  // here I get seg fault

return 0;

一旦删除ptr_s2,就会发生seg错误。

更新:根据接受的答案,正确的方式:

typedef struct my_struct_t{

    int a, b;
    vector<unsigned> vec;
    inline my_struct_t operator=(const my_struct_t &s ){
       a = s.a;
       b = s.b;
       vec = s.vec;
       return s;
    }
} MYSTRUCT;

MYSTRUCT* ptr_s1 =  new MYSTRUCT;
MYSTRUCT* ptr_s2 =  new MYSTRUCT;

for(int i = 0 ; i < 100 ; i++){
    ptr_s1->vec.push_back(i);
}

// no memcpy
// memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));
*ptr_s2 = *ptr_s1;

delete ptr_s1;
delete ptr_s2;  // no more sget seg fault

return 0;

1 个答案:

答案 0 :(得分:9)

您不需要致电std::vector::clear或做其他事情,当您通过delete ptr_s;删除析构函数时,系统会调用析构函数。

still reachable问题在Valgrind FAQ中解释。

  

我的程序使用C ++ STL和字符串类。 Valgrind报道   仍然可以到达&#39;在出口处涉及这些类的内存泄漏   该计划,但应该没有。

     

首先:放松,它可能不是一个错误,而是一个功能。许多   C ++标准库的实现使用自己的内存   池分配器。对于相当多的被破坏物体的记忆是   没有立即释放并返回操作系统,但保留在   游泳池以供日后重复使用。游泳池没有被释放的事实   退出程序导致Valgrind报告此内存为静止   到达。可以调用不在出口处释放池的行为   但是这个库的错误。

<强>更新

简单地说,如果使用memcpy来复制析构函数删除其自身内部指针的类对象(在您的情况下为std :: vector成员),则不要使用memcpy复制类,当对象的第二个实例被销毁时,你最终会得到双重删除。

正确的方法是复制/移动构造函数和/或类的赋值运算符。