我有许多长链表(它们最多有 20,000 个项目)。它们有不同的起点,但它们最终可以从某个节点开始指向同一个节点。我决定让这样的链表一起成长,共享它们之间的记忆。
这就是为什么我决定使用共享指针来实现链表:
#include <memory>
struct SharedLinkedList {
int someData;
std::shared_ptr<SharedLinkedList> next;
};
这样一切正常。不再需要的链表被删除。如果他们与其他链接列表共享某些部分,则仅删除其未共享的部分。
当没有共享部分的较长链表即将被删除时,就会出现问题。删除从第一个元素开始。这减少了对也可以删除的下一个元素的引用数量,并且递归重复直到堆栈溢出。
这是创建长链表然后无法删除它的代码示例。
SharedLinkedList* beginningOfList;
SharedLinkedList* actualElement = new SharedLinkedList();
SharedLinkedList* nextElement;
beginningOfList = actualElement;
for (int i = 0; i < 1000; i++) { // 100 is OK, 1000 is KO
nextElement = new SharedLinkedList();
actualElement->next = std::shared_ptr<SharedLinkedList>(nextElement);
actualElement = nextElement;
}
delete beginningOfList;
我提前感谢以下任何一项:
- 解释 shared_pointers 和我错过了什么。我该如何使用它们?甚至可以使用它们来完成吗?这种内存共享难道不是发明共享指针的目的吗?
- 建议如何重新实现我的代码
- 此代码将用于在我的计算机上运行的科学计算。我可以以某种方式调整一些东西以获得更大的堆栈吗?
请注意,这个问题不是 c++11 特定的。我不在乎使用了共享指针的哪个实现。我什至实现了我自己的共享指针。这让我有一个更长的链表,但也出现了析构函数中的递归和堆栈溢出。而且我看不出如何在没有析构函数递归的情况下实现共享指针。
编辑:
只是为了避免混淆:我想重申整个列表可以共享。所以可以称它们为树。
这是示例:
list1 包含:1,2,3,4,5,6,7。
list2 包含:6,6,6,1,2,3,4,5,6,7
list3 包含:10,11,12,1,2,3,4,5,6,7
我想在 3 SharedLinkedList 中表示这一点,它们不会通过多次存储 1、2、3、4、5、6、7 来浪费内存,但它们指向同一个地方。这就是需要引用计数的原因。
delete list3;
应该只删除不共享的部分,即元素 10、11、12。