C++ 指针重新分配,堆释放后使用

C++ 指针重新分配,堆释放后使用,c++,c++11,C++,C++11,我试图编写一个简单的函数来交换链表的节点(其中的值不能更改,只能更改节点)。在释放错误后运行到内存使用率,我无法锁定它。我相当肯定答案是非常简单明了的,我只是现在看不出来 void swapNodes(ListNode* a, ListNode *b){ //does not consider the root case auto * a1 = a->next; auto * a2 = a1->next; auto * b1 = b->next

我试图编写一个简单的函数来交换链表的节点(其中的值不能更改,只能更改节点)。在释放错误后运行到内存使用率,我无法锁定它。我相当肯定答案是非常简单明了的,我只是现在看不出来

void swapNodes(ListNode* a, ListNode *b){ //does not consider the root case
    auto * a1 = a->next;
    auto * a2 = a1->next;
    
    auto * b1 = b->next;
    auto * b2 = b1->next; // may be nullptr
    
    auto newA = std::make_shared<ListNode>(ListNode(b1->val, a2));
    auto newB = std::make_shared<ListNode>(ListNode(a1->val, b2));
    
    a->next = newA.get();
    b->next = newB.get();
}

一旦
swapNodes
函数返回,将使
a->next
变为无效


简单的解决方案是在此处不使用共享指针。

首先,创建两个共享指针,并分配给局部变量:

    auto newA = std::make_shared<ListNode>(ListNode(b1->val, a2));
    auto newB = std::make_shared<ListNode>(ListNode(a1->val, b2));
最后,函数完成,
newA
newB
超出范围,分配的内存被删除

}

但是,
a->next
b->next
仍然指向由已删除的
std::shared\u ptr
管理的内存,因此您会收到“释放后使用”错误。

请根据需要添加一个。交换需要节点分配的节点看起来可疑。此外,如何处理交换节点的前置节点的更新?@πάνταῥεῖ : 对不起,我认为这个问题很简单,很经典,不需要一个。谢天谢地,我已经有了答案。你不应该把这些值复制到任何地方,包括复制到新的节点。@Kronephon。。。如果你想给我一个快速的答案,请逛商店,你活不了多久。只是说。哦,我太傻了,我可以指着它们,谢谢。据我所知,你的答案是,问题是我不会让对象仍然指向共享指针,而是指向它们的内容没有?因此,当函数的作用域结束时,ref计数为0,对象被销毁。否?感谢您的解释。虽然问题解决了,因为我根本不需要分配任何东西,但我很好奇。在这种情况下,有没有办法不使用new来保持对象的活动性?我想我必须按值返回它,并让调用者进行内存管理。。。
a->next = newA.get();
    auto newA = std::make_shared<ListNode>(ListNode(b1->val, a2));
    auto newB = std::make_shared<ListNode>(ListNode(a1->val, b2));
    a->next = newA.get();
    b->next = newB.get();
}