Valgrind用shared_ptr c ++ 11表示内存泄漏

时间:2018-03-25 16:38:25

标签: c++ c++11 data-structures valgrind

我使用C ++ 11智能指针实现了一个链接列表。此实现使用shared_ptr存储内部数据结构,该结构用于实现对它的隐式共享。我提供了以下源代码的相关部分:

> ==8897== HEAP SUMMARY:
==8897==     in use at exit: 282,976 bytes in 3,757 blocks
==8897==   total heap usage: 10,009 allocs, 6,252 frees, 633,040 bytes allocated
==8897== 
==8897== 136 (24 direct, 112 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 8
==8897==    at 0x4C2E216: operator new(unsigned long) (vg_replace_malloc.c:334)
==8897==    by 0x407C1C: Algos::LinkedList<DataTest>::LinkedList() (linkedlist.h:74)
==8897==    by 0x4074B4: main (insert_delete_rounds.cpp:63)
==8897== 
==8897== 210,136 (24 direct, 210,112 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 8
==8897==    at 0x4C2E216: operator new(unsigned long) (vg_replace_malloc.c:334)
==8897==    by 0x407C1C: Algos::LinkedList<DataTest>::LinkedList() (linkedlist.h:74)
==8897==    by 0x4074C3: main (insert_delete_rounds.cpp:65)
==8897== 
==8897== LEAK SUMMARY:
==8897==    definitely lost: 48 bytes in 2 blocks
==8897==    indirectly lost: 210,224 bytes in 3,754 blocks
==8897==      possibly lost: 0 bytes in 0 blocks
==8897==    still reachable: 72,704 bytes in 1 blocks
==8897==         suppressed: 0 bytes in 0 blocks
==8897== Reachable blocks (those to which a pointer was found) are not shown.
==8897== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8897== 
==8897== For counts of detected and suppressed errors, rerun with: -v
==8897== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

由于使用了 new ,以下代码在shared_pointer构造函数中触发valgrind上的内存泄漏错误:

JENKINS_HOME=/home/alex/JenkinsHome/

这是我在valgrind控制台中收到的消息:

.map {
 height: 100%;
 width:100%;
}

据我所知,没有其他方法可以在不使用 删除 启动shared_ptr >在C ++ 11中。在stackoverflow上阅读文档和不同的线程后,我注意到 std :: make_shared() 不支持传递自定义 Deleter 即可。所以,我的问题是:这个内存泄漏警告是否合法?如果是,是否可以避免它?

开发工具设置:

  • gcc:5.4.0
  • Valgrind:3.13.0
  • 操作系统:Linux Ubuntu 16.04

3 个答案:

答案 0 :(得分:2)

回答你的问题:

  1. 您可以使用RealmResults.addChangeListener来允许使用自定义内存分配器。签名是相同的,除了它将对分配器的const引用作为第一个参数。

  2. 虽然您可以清理LinkedListData的内部,但您delete方法中的分配指针永远不会cleanup。应该从cleanup析构函数调用LinkedListData,您应该使用常规删除器(如果使用自定义分配器,则使用自定义删除器)来调用LinkedListData指针上的删除。

  3. 简而言之,这一行总会导致内存泄漏:

    LinkedList() : d(new LinkedListData<T>(), LinkedListData<T>::cleanup){}
    

答案 1 :(得分:2)

您创建了new LinkedListData<T>(),但未在delete内拨打cleanup

答案 2 :(得分:1)

由于您在内部使用智能指针,因此不应将LinkedListData::cleanup指定为自定义删除器,而只使用默认删除器。如果您试图坚持使用智能指针,那么如果您没有明确调用new,则最好避免使用delete调用。因此,可以使用d初始化d(std::make_shared<LinkedListData<T>>())成员。此外,它可以被声明为LinkedListData<T> d;而没有任何智能指针。

然后,您不应在release中致电LinkedListData::cleanup。此方法将原始指针与智能指针包装器分离,并且不释放关联的对象。您可能需要reset。但是再一次,这个方法根本不是必需的,因为你的所有指针都是智能的,并且在调用父析构函数时应该自动清理相关数据。