我的内存泄漏是由循环引用引起的吗? 我在C++中创建了一个双链表。当添加到列表的前面时,我收到以下内存泄漏: Detected memory leaks! Dumping objects -> {193} normal block at 0x000001F7A1EC01B0, 16 bytes long. Data: < 0 > A0 30 EB A1 F7 01 00 00 00 00 00 00 00 00 00 00 {192} normal block at 0x000001F7A1EB3090, 96 bytes long. Data: < [J > D0 5B 4A AE F7 7F 00 00 02 00 00 00 01 00 00 00 {149} normal block at 0x000001F7A1EBF9E0, 16 bytes long. Data: < # > D8 F7 15 23 E4 00 00 00 00 00 00 00 00 00 00 00 Object dump complete. 检测到内存泄漏! 转储对象-> 0x000001F7A1EC01B0处的{193}正常块,16字节长。 数据:A0 30 EB A1 F7 01 00 00 00 0x000001F7A1EB3090处的{192}正常块,96字节长。 数据:D0 5B 4A AE F7 7F 00 00 00 00 00 0x000001F7A1EBF9E0处的{149}正常块,16字节长。 数据:D8 F7 15 23 E4 00 00 对象转储完成。

我的内存泄漏是由循环引用引起的吗? 我在C++中创建了一个双链表。当添加到列表的前面时,我收到以下内存泄漏: Detected memory leaks! Dumping objects -> {193} normal block at 0x000001F7A1EC01B0, 16 bytes long. Data: < 0 > A0 30 EB A1 F7 01 00 00 00 00 00 00 00 00 00 00 {192} normal block at 0x000001F7A1EB3090, 96 bytes long. Data: < [J > D0 5B 4A AE F7 7F 00 00 02 00 00 00 01 00 00 00 {149} normal block at 0x000001F7A1EBF9E0, 16 bytes long. Data: < # > D8 F7 15 23 E4 00 00 00 00 00 00 00 00 00 00 00 Object dump complete. 检测到内存泄漏! 转储对象-> 0x000001F7A1EC01B0处的{193}正常块,16字节长。 数据:A0 30 EB A1 F7 01 00 00 00 0x000001F7A1EB3090处的{192}正常块,96字节长。 数据:D0 5B 4A AE F7 7F 00 00 00 00 00 0x000001F7A1EBF9E0处的{149}正常块,16字节长。 数据:D8 F7 15 23 E4 00 00 对象转储完成。,c++,shared-ptr,smart-pointers,doubly-linked-list,C++,Shared Ptr,Smart Pointers,Doubly Linked List,这是我的代码: struct Node { bool exists = false; int element; shared_ptr<node> prevNode = nullptr; shared_ptr<node> nextNode = nullptr; }; class DLL { public: shared_ptr<Node> frontNode = make_shared<Node>();

这是我的代码:

struct Node {
    bool exists = false;
    int element;
    shared_ptr<node> prevNode = nullptr;
    shared_ptr<node> nextNode = nullptr;
};

class DLL {
public:
    shared_ptr<Node> frontNode = make_shared<Node>();
    shared_ptr<Node> backNode = make_shared<Node>();
    void frontAdd(int x);
}

void DLL::frontAdd(int x) {
    shared_ptr<Node> tempNode = make_shared<Node>();
    tempNode->exists = true;
    tempNode->element = x;
    tempNode->prevNode = nullptr;

    if (frontNode->exists) {
        tempNode->nextNode = frontNode;
        frontNode->prevNode = tempNode;
    }
    else {
        backNode = tempNode;
    }

    frontNode = tempNode;
};
struct节点{
bool exists=false;
int元素;
共享\u ptr prevNode=nullptr;
shared_ptr nextNode=nullptr;
};
类DLL{
公众:
shared_ptr frontNode=make_shared();
shared_ptr backNode=使_共享();
无效前加(整数x);
}
void DLL::frontAdd(int x){
shared_ptr tempNode=使_共享();
tempNode->exists=true;
tempNode->element=x;
tempNode->prevNode=nullptr;
如果(frontNode->存在){
tempNode->nextNode=frontNode;
frontNode->prevNode=tempNode;
}
否则{
backNode=tempNode;
}
frontNode=tempNode;
};
我曾尝试使用独特的指针和弱指针,但我不熟悉弱指针,作为初学者,我发现很难将它们与本项目集成。 我已尝试删除frontNode和tempNode上的make_shared,而不是在没有make_shared的情况下创建它们,但在这两种情况下,这都会返回写访问冲突,即“returned nullptr”。在autos中,tempNode为空,因此这是有意义的


由于shared_ptr超出了范围,我预计所有所有权都将丢失,内存泄漏将不存在,但我猜是因为“make_shared”它已添加到堆中,因此无法如此轻松地从内存中删除?

原因可能是您的循环引用。shared\u ptr没有那么聪明,只是简单地计算引用的数量,而返回指针将计数保持为非零

对于任何可能被视为“后退”指针的对象,您需要使用原始指针或弱指针,无论是来自从属子对象,还是具有双向列表的对象


弱\u ptr
有一个操作成本,但有一个优点,即子对象只需很少的编码工作就可以安全地运行。

很可能是您的循环引用造成的。共享\u ptr没有那么聪明,只需计算引用的数量,并且返回指针使计数不为零

对于任何可能被视为“后退”指针的对象,您需要使用原始指针或弱指针,无论是来自从属子对象,还是具有双向列表的对象


弱\u ptr
有一个操作成本,但有一个优点,即子对象只需很少的编码工作就可以安全地运行。

是的,您对所有节点都有循环依赖关系。每个节点指向下一个节点和前一个节点,因此每个节点都有多个循环依赖关系,除了头部和尾部


例如,您可以通过对上一个链接使用
弱\u ptr
来解决此问题。这会导致性能下降,因为您需要从弱指针获取新的共享指针来访问以前的节点。

是的,您对所有节点都有循环依赖关系。每个节点都指向下一个节点和上一个节点,因此需要多个ci每个节点的RCURAL依赖项,位于头部和尾部之外


例如,您可以通过对上一个链接使用
弱\u ptr
来修复此问题。这将导致性能下降,因为您需要从弱指针获取新的共享指针来访问以前的节点。

是引用计数的,所以是的,您通常会期望这样的循环导致泄漏。这是存在的原因之一首先。你知道当你的DLL对象被销毁时会发生什么,所有共享指针都处于什么状态吗?也不知道为什么你需要“存在”标志-你可以只测试frontNode共享指针是否被设置。如果它是列表中唯一的指针,prevNode和nextNode将是nullptr,不管它是否存在不管是不是sts,这对于第一次创造是必要的least@Useless
弱\u ptr
的原因不是“中断循环”。事实上,根据定义,所有权循环不可能存在。循环是一个bug。你想要std容器语义吗?比如
std::list
?这意味着每个元素的所有者都是容器,当容器被销毁、清除时,以及当迭代器引用的元素被删除时,迭代器都会失效。是吗引用计数所以是的,您通常希望这样的循环会导致泄漏。这是存在的原因之一。您知道当您的DLL对象被销毁时会发生什么,以及所有共享指针处于什么状态吗?也不确定为什么需要“存在”标志-您可以只测试frontNode共享指针是否r是否已设置。如果它是列表中的唯一指针,则prevNode和nextNode将是nullptr,而不管它是否存在,因此在least@Useless
弱\u ptr
的原因不是“中断循环”事实上,根据定义,所有权的循环是不存在的。循环是一个bug。你想要std容器语义吗?比如
std::list
?它意味着每个元素的所有者都是容器,当容器被销毁、清除时,以及当迭代器引用的元素被删除时,迭代器都会失效。“子对象可以安全地运行”,但它需要能够正确处理引用对象已被释放的情况。对于那些懒得阅读另一个答案下的聊天线程的人:此注释是错误的,两个答案都是正确的。共享指针是