如何解决shared_ptr的循环引用问题,而不使用weak_ptr?

3

我已经调试了几个小时的内存泄漏问题,结果发现程序中有循环引用。

网上提供的解决方法是将shared_ptr转换成weak_ptr,但是这个任务中要求我们使用shared_ptr

基本上,这个程序是一个文件系统。就像当你输入cd .时,你会进入当前的地址。

  1. currentAddress是一个指向当前地址的inode_ptr
  2. directory被定义为map<string, inode_ptr<node>>,其中directory.first是文件名/目录名,如...fileA,而directory.second是一个inode_ptr,与currentAddress相同。

所以我想要做的就是将pair<".", currentAddress>放入directory中。

并且currentAddress也应该指向directory

在不使用weak_ptr的情况下,如何避免这种情况下的内存泄漏?谢谢!


其实,你甚至需要在给定的目录中放置{".", currentAddress}吗?因为它总是被隐含了。 - Galik
@Galik 是的,实际上 currentAddressdirectory 是在两个不同的类中,并且它们是私有的。 - Kevin217
目录结构只是一个简单的树形结构(对于 ... 有特殊情况)吗?或者同一个 inode 可以出现在两个不同的目录中吗? - Galik
@Galik directory 是一个映射,或者你可以称之为一个 map。directory.second 是一个指向 file 类或 directory 类的 shared_ptr。但在这种情况下,内存泄漏发生在 . 处。 - Kevin217
1个回答

4

在此处使用弱指针是无法避免的。这就是现实,它就是这样。

但是,在这里可以做一些事情来最小化使用弱指针,并将其大部分隐藏为内部实现细节,您的虚拟文件系统的用户只会看到普通的强指针。

首先要注意的是,每个虚拟目录都始终有一个“。”和“..”的条目。这意味着您不需要在directory映射中存储实际的“。”和“..”条目。 directory映射仅包含目录的实际内容条目。

然后,您需要做一些工作,以提供自定义迭代器或某种包装器,将迭代器围绕directory映射进行包装,并用相应的inode_ptr<node>合成“。”和“..”项。

您的虚拟文件系统的用户不会直接访问directory容器,这是一个私有实现细节。相反,您将提供适当的方法来构建外观迭代器,覆盖包括底层directory映射中的所有条目以及即时合成的“。”和“..”条目的虚拟容器。

为了避免循环引用,您模拟的文件系统中的每个目录都需要持有对其父目录的弱指针。没有其他方法可以避免循环引用。但这应该没问题。只要父目录存在并且持有对其子目录的强指针,从子目录到父目录的弱指针就会保持有效。您的迭代器/容器外观将需要从弱指针中恢复一个强指针,并将其作为与“..”条目相关联的所谓强指针返回。类似地,directory映射的外观将构造对自身的强指针,并将其作为“.”条目的值返回。

最终结果是,您的虚拟文件系统的用户仍然使用常规的强指针,而在幕后,您将使用从目录到其父目录的弱指针来防止循环引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接