我使用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 即可。所以,我的问题是:这个内存泄漏警告是否合法?如果是,是否可以避免它?
开发工具设置:
答案 0 :(得分:2)
回答你的问题:
您可以使用RealmResults.addChangeListener来允许使用自定义内存分配器。签名是相同的,除了它将对分配器的const引用作为第一个参数。
虽然您可以清理LinkedListData
的内部,但您delete
方法中的分配指针永远不会cleanup
。应该从cleanup
析构函数调用LinkedListData
,您应该使用常规删除器(如果使用自定义分配器,则使用自定义删除器)来调用LinkedListData
指针上的删除。
简而言之,这一行总会导致内存泄漏:
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
。但是再一次,这个方法根本不是必需的,因为你的所有指针都是智能的,并且在调用父析构函数时应该自动清理相关数据。