使用共享指针创建的链表数组

Posted

技术标签:

【中文标题】使用共享指针创建的链表数组【英文标题】:An array of linked lists created with shared pointers 【发布时间】:2015-03-26 20:21:10 【问题描述】:

我有一个大小为 N 的数组。所有数组元素都是使用共享指针创建的单链表。这些链表由称为 S 的结构组成。这些 S 元素具有一些数据和指向下一个 S 元素的 shared_ptr。 array[i]链表最后一个S元素指向nullptr。

当我想清空数组时,如何让共享指针释放所有内存?

一个简单的 for 循环执行 array[i] = nullptr;不会做吗?还是会?

我已经尝试过使用 shared_ptr 指向下一个 S 和普通指针指向前一个 S 的双向链表,但是由于普通指针不能放在 shared_ptr 上,所以当我到达链接的末尾时,我不能倒退list(我需要走到最后,这样我就可以一次倒退一个 S 并通过使 last-1 元素指向 nullptr 来释放当前最后一个元素。)。

并且双重不适用于 next = shared_ptr 和 previous = shared_ptr 因为元素会相互指向并且共享指针永远无法释放内存。

或者我应该以不同的方式处理数组还是只使用普通指针?

【问题讨论】:

使用普通指针。或者,为什么不 std::list? 【参考方案1】:

回答你的第一个问题,对象类型

std::shared_ptr<T>

共享他们的所有权,只有在最后一个 shared_ptr 被销毁时才删除托管对象。但是,您可以通过调用使 shared_ptr 释放其托管对象

std::shared_ptr<T>::reset

见std::shared_ptr::reset

此外,调用此函数的副作用与在其值更改之前调用 shared_ptr 的析构函数具有相同的副作用(如果此 shared_ptr 是唯一的,则包括删除托管对象)。

作为链表的构建块,不要使用 shared_ptr,使用普通指针。 引用 Bjarne Stroustrup 的“The C++ Programming Language”,

仅当您确实需要共享所有权时才使用 shared_ptr。

【讨论】:

我将共享指针更改为普通指针。但是想想最初的困境:当我将 shared_ptr @array[i] 设置为 nullptr 时,这不会使 shared_ptr 指向的元素消失吗?当那个元素消失时,shared_ptr 也会消失到下一个元素......当它不再存在时,没有任何东西指向下一个元素。那么,在这种情况下,共享指针会像多米诺骨牌效应一样释放内存吗? "不拥有任何指针的 shared_ptr 称为空 shared_ptr。不指向任何对象的 shared_ptr 称为空 shared_ptr 且不应被取消引用。请注意,空的 shared_ptr 不一定一个空的 shared_ptr,一个空的 shared_ptr 不一定是一个空的 shared_ptr。” (来自 cplusplus.com)设置指向 nullptr 的指针不会“删除”它指向的对象,它只是使指针不指向任何东西。 make_shared 创建的对象在指向它的shared_ptr 设置为nullptr 时会发生什么情况? 其实设置一个shared_ptr为nullptr实际上调用reset(),所以你可以选择你想要的(调用reset或者设置为nullptr)。指向的对象被销毁。【参考方案2】:

好像

array[i] = nullptr;

确实释放所有内存,因为 array[i] 是 shared_ptr 并将其设置为 nullptr “删除”(如 jensa 所述,调用 reset())shared_ptr 指向的对象,同时删除 shared_ptr(对象的)到下一个对象,因此下一个对象也被删除......这一直持续到数组 [i] 的链表中没有 shared_ptrs/objects。

【讨论】:

以上是关于使用共享指针创建的链表数组的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode138. 复制带随机指针的链表/1893. 检查是否区域内所有整数都被覆盖/370. 区间加法(差分数组+前缀和)

如何用数组实现一个紧凑的链表?

PTA数据结构链表共享后缀的链表

是否可以创建一个可以保存指针而不是整数或字符串的链表?

用于实现堆栈的链表与动态数组

静态链表