分配包含 stl 向量的结构时内存泄漏
Memory leaks when allocating struct containing 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;
}
我尝试使用 clear
因为它应该调用析构函数。但是在 valgrind
-ing 我的代码之后,仍然有一些块可以到达。我也尝试使用这个解除分配向量:
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
,段错误就发生了。
更新:正确的方法,基于接受的答案:
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;
您不需要调用 std::vector::clear
或执行其他操作,当您通过 delete ptr_s;
.
删除它时,析构函数将被调用
still reachable
问题在 Valgrind FAQ 中有解释。
My program uses the C++ STL and string classes. Valgrind reports
'still reachable' memory leaks involving these classes at the exit of
the program, but there should be none.
First of all: relax, it's probably not a bug, but a feature. Many
implementations of the C++ standard libraries use their own memory
pool allocators. Memory for quite a number of destructed objects is
not immediately freed and given back to the OS, but kept in the
pool(s) for later re-use. The fact that the pools are not freed at the
exit of the program cause Valgrind to report this memory as still
reachable. The behaviour not to free pools at the exit could be called
a bug of the library though.
更新:
简而言之,如果您使用 memcpy
复制一个 class 对象,其析构函数删除了自身内部的指针(std ::vector 成员在你的情况下),当对象的第二个实例被销毁时,你将以双重删除结束。
正确的方法是 copy/move constructor and/or assignment operator for classes.
我想为包含 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
-ing 我的代码之后,仍然有一些块可以到达。我也尝试使用这个解除分配向量:
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
,段错误就发生了。
更新:正确的方法,基于接受的答案:
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;
您不需要调用 std::vector::clear
或执行其他操作,当您通过 delete ptr_s;
.
still reachable
问题在 Valgrind FAQ 中有解释。
My program uses the C++ STL and string classes. Valgrind reports 'still reachable' memory leaks involving these classes at the exit of the program, but there should be none.
First of all: relax, it's probably not a bug, but a feature. Many implementations of the C++ standard libraries use their own memory pool allocators. Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.
更新:
简而言之,如果您使用 memcpy
复制一个 class 对象,其析构函数删除了自身内部的指针(std ::vector 成员在你的情况下),当对象的第二个实例被销毁时,你将以双重删除结束。
正确的方法是 copy/move constructor and/or assignment operator for classes.