使用共享指针创建的链表数组
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. 区间加法(差分数组+前缀和)