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

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)

Alp*_*per 9

您不需要调用std::vector::clear或执行其他操作,当您通过析构函数删除它时,它将被调用delete ptr_s;.

still reachable事项已于Valgrind的解释常见问题.

我的程序使用C++ STL和字符串类.Valgrind报告在程序退出时涉及这些类的"仍然可达"的内存泄漏,但应该没有.

首先:放松,这可能不是一个错误,而是一个功能.许多C++标准库的实现都使用自己的内存池分配器.很多被破坏对象的内存不会立即被释放并返回给操作系统,而是保存在池中以供以后重复使用.在程序退出时未释放池的事实导致Valgrind报告此内存仍可访问.不要在出口处释放池的行为可以称为库的错误.

更新:

简单来说,不要复制类memcpy,如果你memcpy用来复制析构函数删除其自身内的指针的类对象(在你的情况下是std :: vector成员),那么当对象的第二个实例是销毁.

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