我想为包含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)
但没有成功。
==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;
答案 0 :(得分:9)
您不需要致电std::vector::clear
或做其他事情,当您通过delete ptr_s;
删除析构函数时,系统会调用析构函数。
still reachable
问题在Valgrind FAQ中解释。
我的程序使用C ++ STL和字符串类。 Valgrind报道 仍然可以到达&#39;在出口处涉及这些类的内存泄漏 该计划,但应该没有。
首先:放松,它可能不是一个错误,而是一个功能。许多 C ++标准库的实现使用自己的内存 池分配器。对于相当多的被破坏物体的记忆是 没有立即释放并返回操作系统,但保留在 游泳池以供日后重复使用。游泳池没有被释放的事实 退出程序导致Valgrind报告此内存为静止 到达。可以调用不在出口处释放池的行为 但是这个库的错误。
<强>更新强>
简单地说,如果使用memcpy
来复制析构函数删除其自身内部指针的类对象(在您的情况下为std :: vector成员),则不要使用memcpy
复制类,当对象的第二个实例被销毁时,你最终会得到双重删除。
正确的方法是复制/移动构造函数和/或类的赋值运算符。