本文介绍了了解“底层C/C++对象已被删除"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是我第一次收到 RuntimeError:底层 C/C++ 对象已被删除.我已经解决了很多次以随机但直观的方式更改我的代码,但现在我再次面临这个问题,只是不明白为什么会发生这种情况......我要的是一种通用的方法来面对和解决这个错误.

It's not the first time I am getting the RuntimeError: underlying C/C++ object has been deleted. I've solved it many times altering my code in a random but intuitive way but now I am facing this again and just don't understand why it happens...What I ask for is a generic approach to confront and solve this error.

我不会在这里发布代码示例,因为我的项目太复杂了,我无法弄清楚错误在哪里.也因为我要求的不仅仅是这种情况的通用解决方案.

I will not post code samples here because my project is too complex and I just can't figure out where's the bug. And also because I am asking for the universal solution not just for this case.

为什么可以删除底层 C/C++"对象?
如何避免?
如何测试底层对象是否存在?

推荐答案

您无法测试底层对象是否存在(例如,它是否已被删除").您可以使用一些技巧"来有点"帮助解决此问题,但我不建议这样做.相反,恕我直言,我猜你的设计缺乏强大的所有权语义.(根据问题的复杂程度和您的域,这可能是必要的,但如果可以避免,我建议您不要这样做.)

You cannot test if the underlying object exists (e.g., if it has been "deleted"). There is some "trickery" you can employ to "kind-of" help with this, but I don't recommend it. Rather, IMHO, I'd guess your design lacks strong ownership semantics. (That may be necessary depending on the complexity of the problem and your domain, but I'd recommend against it, if it is avoidable.)

您的问题是所有权语义.尤其是在 C++ 中,与使用内存垃圾收集"的其他语言相反,您必须有一个设计,其中您对谁拥有什么"有深刻的理解.您的设计应该简单明了"地了解存在哪些对象,以及谁拥有"它们.

Your problem is ownership semantics. Most especially in C++, as opposed to other languages that employ memory "garbage collection", you MUST have a design where you have a strong understanding of "who owns what". Your design should make it "easy and obvious" to know what objects exist, and who "owns" them.

通常,这意味着将对象的创建"和删除"集中到某种父对象"中,在那里永远不会有关于这是谁的对象?"的问题.以及您管理的对象是什么?"

Generally, this means to centralize the "creation" and "deletion" of objects into a "parent" of some kind, where there is never any question as to, "Whose object is this?" and "What are your objects that you manage?"

例如,父"类将分配它需要"的成员对象,并且只有该父类会删除这些对象.父级的析构函数确保删除这些成员,因此这些对象不会意外地留下".因此,父对象知道"其成员对象,当父对象消失时,您知道成员对象也消失了.如果您的设计是强耦合的,那么成员对象可能会引用父对象,但这是所有权语义的池的深端"(通常不推荐).

For example, a "Parent" class will allocate member objects that it "needs", and only that parent deletes those objects. The parent's destructor ensures those members are deleted, so those objects don't accidentally get "left around". Thus, the parent "knows" its member objects, and when the parent is gone, you KNOW the member objects also are gone. If your design is strongly coupled, then the member objects may reference the parent object, but that is the "deep end of the pool" for ownership semantics (and usually not recommended).

有些设计可能非常复杂.但是,总的来说,所有权语义永远不应该复杂:您应该始终知道谁拥有什么",因此,您应该始终知道存在哪些对象".

Some designs can be legitimately very complicated. However, in general, ownership semantics should NEVER be complicated: You should ALWAYS know "who owns what", and thus, you should ALWAYS know "what objects exist".

其他设计也可以使用垃圾收集语言,其中对象可能是自由代理",并且您相信垃圾收集器会完成清理您丢失跟踪的对象的繁重工作".(我不偏爱这些设计,但承认它们有时在其他语言中是可以接受的,基于独特的问题域.)

Other designs are possible with garbage collection languages, where objects may be "free agents" and you trust the garbage collector to do the "hard work" of cleaning up objects about which you've lost track. (I'm not partial to those designs, but concede them to be sometimes acceptable in those other languages, based on unique problem domains.)

如果您的 C++ 设计依赖于此类自由代理"对象,您可以编写自己的垃圾收集器或自己的实用程序所有者"来清理它们.例如,MyFreeAgent 构造函数可以向 MyGarbageCollector 注册自己,而 MyFreeAgent 析构函数将从 MyGarbageCollector 注销自己>.因此,MyFreeAgent 实例可以被 MyGarbageCollector 清理",或者 MyFreeAgent 甚至可以通过delete this;",你就会知道它已经消失了(因为它的析构函数会从 MyGarbageCollector 中注销自己).在此设计中,单个 MyGarbagageCollector 将始终知道"存在哪些 MyFreeAgent 实例.

If your C++ design relies upon such "free agents" objects, you can write your own garbage collector, or own "utility owner" to clean them up. For example, the MyFreeAgent constructor could register itself with the MyGarbageCollector, and the MyFreeAgent destructor would unregister itself from the MyGarbageCollector. Thus, MyFreeAgent instances could be "cleaned up" by the MyGarbageCollector, or the MyFreeAgent could even kill itself with "delete this;", and you would KNOW that it is gone (because its destructor would unregister itself from the MyGarbageCollector). In this design, a single MyGarbagageCollector would ALWAYS "know" what MyFreeAgent instances exist.

此类设计是池的深处",即使它们有效,也应极其谨慎地使用,因为它们具有大规模解构您的系统的强大潜力.(我已经使用过它们,但您必须得到确定问题确实需要这样的设计.)

Such designs are the "deep end of the pool" and should be used with extreme caution, even though they work, because they have the strong potential to massively de-structure your system. (I've used them, but you've got to be sure the problem honestly warrants such a design.)

这篇关于了解“底层C/C++对象已被删除"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-04 04:00