分配包含 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.