Ham*_*ani 1 c++ struct memory-leaks stl vector
我想为包含的结构分配内存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;
}
Run Code Online (Sandbox Code Playgroud)
我试图使用,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
Run Code Online (Sandbox Code Playgroud)
提前谢谢大家.
更新:
我注意到我的应用程序中的内存损坏源是在其他地方.所以我添加了更新.这是新代码:
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;
Run Code Online (Sandbox Code Playgroud)
一旦删除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;
Run Code Online (Sandbox Code Playgroud)
您不需要调用std::vector::clear或执行其他操作,当您通过析构函数删除它时,它将被调用delete ptr_s;.
该still reachable事项已于Valgrind的解释常见问题.
我的程序使用C++ STL和字符串类.Valgrind报告在程序退出时涉及这些类的"仍然可达"的内存泄漏,但应该没有.
首先:放松,这可能不是一个错误,而是一个功能.许多C++标准库的实现都使用自己的内存池分配器.很多被破坏对象的内存不会立即被释放并返回给操作系统,而是保存在池中以供以后重复使用.在程序退出时未释放池的事实导致Valgrind报告此内存仍可访问.不要在出口处释放池的行为可以称为库的错误.
更新:
简单来说,不要复制类memcpy,如果你memcpy用来复制析构函数删除其自身内的指针的类对象(在你的情况下是std :: vector成员),那么当对象的第二个实例是销毁.
正确的方法是复制/移动构造函数和/或类的赋值运算符.