我有许多长链接列表(它们最多有 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 特定的。我不关心使用哪种共享指针的实现。我什至实现了我自己的共享指针。这使我可以拥有更长一点的链表,但析构函数中的递归和堆栈溢出也出现了。而且我看不出有什么方法可以在析构函数中不递归的情况下实现共享指针。
EDIT:
为了避免混淆:我想重复一遍,整个列表可以共享。所以人们可以称它们为树。
这是示例:
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。