共享指针递归删除递归数据结构导致堆栈溢出

2024-03-16

我有许多长链接列表(它们最多有 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;

我预先感谢以下任何一项:

  1. Shared_pointers 的解释以及我所缺少的内容。我该如何使用它们?甚至可以使用它们来完成吗?共享指针的发明不就是为了这种内存共享吗?
  2. 建议如何重新实现我的代码
  3. 该代码将用于在我的计算机上运行的科学计算。我可以调整一些东西以获得更大的堆栈大小吗?

请注意,这个问题不是 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。


如果你使用shared_ptr它将为您管理所有权。当引用计数变为 0 时,它将调用指针对象的析构函数。现在,指向的对象被破坏,并且作为它的一个元素,下一个共享指针将破坏下一个......。这导致以递归方式释放内存。现在您可以尝试迭代释放内存。您只需保留对下一个元素的引用以避免其被破坏,并稍后手动删除它:

void destroy(SharedLinkedList* l) {
  auto next=l->next;  // take 2nd element 
  delete l;           // delete first

  while (next)
    next=next->next;  // move next forward, deleting old next 
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

共享指针递归删除递归数据结构导致堆栈溢出 的相关文章

  • 我的 std::hash for std::tuples...有什么改进吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有些人可能已经注意到 std hash 不支持元组 所以我添加了一个重载 它看起来比我到目前为止看到的解决方案 更好 有人有进一步减少这段代码的
  • 如何在 ASP.NET MVC 中将 XML 文件发送到客户端

    在 ASP NET MVC 中 我有一个数据库表 我想在某个视图页面上有一个按钮 如果某个用户单击该按钮 我的应用程序将生成包含数据库中所有行的 XML 文件 然后 应将包含 XML 的文件发送到客户端 以便用户看到下载弹出窗口 同样 我希
  • 如何使用 Entity Framework 和 Identity 解决对象处置异常 ASP.NET Core

    我正在尝试编写一个控制器 该控制器接收来自 AJAX 调用的请求并通过 DBContext 对数据库执行一些调用 但是 当我发出命令时var user await GetCurrentUserAsynch 在对 DBContext 的任何调
  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • 如何在 C++ 和 QML 应用程序中使用 qrc?

    我在 Windows7 上用 c qnd Qt Creator QML 编写了 Qt Quick Desktop 应用程序 现在 我必须部署它 并且我需要隐藏 qml 文件和图像 意味着 将它们放入资源等中 我读到有一个很好的方法可以使用
  • 模板与非模板类,跨编译器的不同行为

    我在一些应用程序中使用编译时计数器 它确实很有用 昨天我想用 gcc 编译一个程序 我之前使用的是 msvc 并且计数器的行为在模板类中发生了变化 它在模板类中不再工作 过于简化的代码 Maximum value the counter c
  • 列表到优先队列

    我有一个 C 大学编程项目 分为两个部分 在开始第二部分时应该使用priority queues hash tables and BST s 我 至少 在优先级队列方面遇到了麻烦 因为它迫使我自己重做第一部分中已经实现的许多代码 该项目是关
  • ASP.net WebForms - 在标记中使用 GetRouteUrl

    我一直在尝试弄清楚如何将路由功能与 ASP net 4 0 WebForms 一起使用 我将一条路线添加到我的路线集合中 void Application Start RegisterRoutes RouteTable Routes voi
  • 如果finally 块包含await,为什么*有时*不会在ThreadAbortException 上执行?

    UPDATE 我不认为这个问题是重复的ThreadAbortException最后可以跳过吗 https stackoverflow com questions 18002668 can threadabortexception skip
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 从具有相同属性的另一个对象创建对象

    我有一个 C 对象 可以说有 20 个属性 它是数据契约的一部分 我还有另一个具有类似属性的业务实体 我想从响应对象中填充该实体 除了将一个对象的每个属性分配给另一个对象的相应属性之外 还有其他方法可以做到这一点吗 是的 看看自动映射器 h
  • 'iter' 的名称查找已更改为新的 ISO 'for' 范围

    我正在尝试编译下面的两个文件 但从编译器收到错误消息 gcc 4 3 3 Linux 错误位于带有以下符号的行 LINE WITH ERROR 我做错了什么 我该怎么改变 路易斯 g c b h b cpp b cpp In functio
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 在 C# 中使用自定义千位分隔符

    在显示字符串时 我尝试不使用 字符作为千位分隔符 而是使用空格 我想我需要定义一种自定义文化 但我似乎做得不对 有什么指点吗 例如 将 1000000 显示为 1 000 000 而不是 1 000 000 no String Replac
  • 如何通过API退出Win32应用程序?

    我有一个使用 Win32 API 编写的 C Win32 应用程序 我希望强制它在其中一个函数中退出 有没有类似的东西Exit or Destroy or Abort 类似的东西会终止它吗 哎呀呀呀呀呀呀 不要做任何这些事情 exit 和
  • 创建进程默认浏览器

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 我想获取线程 id 因此 ShellExecute 无法获取线程 id 因此我开始使用

随机推荐

  • github“网络推送通知”如何工作?

    github 似乎在其 Web 界面上使用轮询服务器进行实时通知 live github com 看起来该技术既不是基于 Websocket 也不是 XHR 轮询 它是如何开发的 他们似乎使用 HTML5 服务器发送事件 一段时间后 我通过
  • 为什么暂存目录也称为 Index/Git Index?

    我对 Git 中的暂存目录 Git Index 的命名感到困惑 叫Index有什么特殊含义吗 为什么不直接称为Cache 或Temp目录以便我们更容易理解呢 对我来说 索引可以帮助我们更快地搜索内容 就像 DBMS 中的索引一样 它与暂存区
  • 如何设置 Amazon S3 存储桶预签名 URL 过期时间(从当前日期算起 1 年内)

    图像上传到 Amazon S3 存储桶 我需要得到一个预签名 URL来自亚马逊服务器 我还想设置该 URL 的到期时间 这最多只需要 17 天 但我无法设置最多 1 年的到期时间 Calendar cal Calendar getInsta
  • 如何 Invoke-Expression 调用带有变量的函数或脚本?

    我使用此脚本收到无效路径错误 buildZIP starmatic echo buildZIP command XXXXXXXXXX L Gopi Prod App ToZipNew ps1 buildZIP Invoke Expressi
  • JPA 配置布尔字段以保留为整数

    在 JPA 中 有一个注释指定布尔字段应保留为整数 我正在使用 OpenJPA 它当前将布尔字段保留为位 我宁愿使用整数 1 或 0 您可以指定列定义 Column name boolColumn columnDefinition INT
  • 导航栏不显示

    这里我有2个看法 欢迎VC WebViewVC First 应用程序代理 calls 欢迎VC通过下面的代码 void presentWelcomeViewController WelcomeViewController welcomeVi
  • 为每个 cURL 请求返​​回 AJAX 结果

    基本上 我的想法是做某种形式的 实时 cURL 结果 正在生产的系统实时结果例如 当执行每个请求时 我将有一个表 其中包含需要通过 cURL 请求访问的网站列表 其中根据每个 cURL 响应的结果 我需要使用 AJAX 将数据发送回我的页面
  • 循环语句的 freemarker 模板

    我想在 freemarker 模板中创建 for 语句 我正在阅读指南http freemarker sourceforge net http freemarker sourceforge net 但只有清单 我如何创建 for 语句或 f
  • 关于将临时绑定到构造函数中的引用成员的虚假警告

    据我所知 如果临时对象绑定到构造函数的初始值设定项列表中的引用成员 则该对象将在构造函数返回时被销毁 However 考虑以下代码 include
  • 使用 jQuery 重新排序 div

    是否可以使用 jQuery 对某些 div 重新排序 我有几个 div 我想根据 div 中的数据索引号在页面加载时重新排序它们 Now div class score 3 div div class score 2 div div cla
  • 如何在 Vagrant 和 Homestead 中回滚 PHP 版本?

    因此 我的公司正在使用 PHP 和 Laravel 为客户进行软件开发 我是公司的新人 正在使用 VirtualBox 设置较新的 Macbook 使用 Homestead 和 Vagrant 设置 Laravel 我已经完成了所有设置 以
  • Lua 中对 Table[] 进行排序

    我有一个 Lua 表 我正在尝试对其进行排序 该表的格式如下 tableOfKills PlayerName NumberOfKills 这意味着 例如 如果我有一个名为 Robin 的玩家总共击杀 8 次 而另一个名为 Jon 的玩家总共
  • TFS2012 - 无法上传大于 5MB 的文件

    我正在虚拟机 Windows Azure 内 上运行 TFS 2012 安装 一切工作正常 除了无法签入大于 5MB 的文件 在客户端 它显示 请求已中止 请求已取消 在服务器端 事件日志包含一条错误消息
  • 更改两级 DropdownButtonFormField :应该只有一项具有 [DropdownButton] 的值

    尽管这里有多个条目似乎有类似的问题 但我无法让它真正发挥作用 我有两个依赖的 DropdownButtonFormFields 的设置 其中第二个在第一个列表更改后更改为另一个列表 我能够将问题分解为第二个选择的选定值的持续剩余 我预计它会
  • 如果我使用 APNs 身份验证密钥,是否需要 APNs 证书?

    我正在使用 Flutter 和 Firebase 编写一个跨平台应用程序 我一直致力于发送通知 它在 Android 上完美运行 我通过 firebase 管理功能 sdk 发送消息 没有任何问题 该请求如下所示 const payload
  • 'UITableView' 没有 @interface 声明选择器 'initWithStyle:reuseIdentifiers

    我是 iOS 开发新手 正在寻求有关 UITableView 问题的帮助 好吧 我正在研究有关 UITableView 代码的所有内容 并且在开发过程中 当我尝试重用标识符时 如果界面上没有要创建的单元格 XCode 会显示以下消息 UIT
  • gnuplot:图例隐藏在数据后面

    我是 gnuplot 的新手 在绘制堆积直方图时 我发现图例隐藏在数据后面 有没有办法将图例放在数据上方 非常感谢你的帮助 编辑 我目前正在使用设置键外部底部将图例放置在外部 但这不是我想要的最佳解决方案 最近的版本允许将图例的背景设为白色
  • Unity3D 中 Update() 循环方法内的执行顺序

    我正在尝试找到合适的词语来描述我遇到的问题 希望这能解释问题 我有两个Update 两个不同类中的方法 并且一个类中的某些功能依赖于另一个类中的数据 代码 A 依赖于代码 B 的数据 使用调试日志 我发现代码B的Update 在代码 A 之
  • 如何从 HttpPost Create 操作方法中了解选定的复选框?

    我之间有多对多关系Student and Course 链接实体集是Enrollment 为了简单起见 它们都定义如下 Models public class Course public int Id get set public stri
  • 共享指针递归删除递归数据结构导致堆栈溢出

    我有许多长链接列表 它们最多有 20 000 个项目 它们有不同的起点 但最终可以从某个节点开始指向同一个节点 我决定让这样的链表一起成长并共享它们之间的记忆 这就是为什么我决定使用共享指针实现链表 include