C ++删除具有有效地址的指针

时间:2011-08-08 11:13:01

标签: c++ memory-management fork shared-ptr poco

我正在使用Poco C ++库并导致奇怪的问题。 Poco使用自己的共享指针类SharedPtr进行内部指针操作。在我的情况下,静态对象Poco::SSLManager具有SharedPtr个证书处理程序对象的成员。当程序运行结束时,静态对象被删除,我抓住了分段错误。 使用GDB调试器,我看到核心转储,不明白问题。删除SharedPtr对象时出现Seg错误(简单操作:delete pObj),但对象具有有效地址,例如 - 0x8fcbed8

为什么删除带有效地址的指针会导致分段错误? 可能是因为对象在应用程序的fork副本中创建并在main中销毁?

4 个答案:

答案 0 :(得分:11)

有效地址只是一个可访问的地址。这并不意味着它适合删除。您只能 deletenew获得的内容。如果你没有new它,则不能delete它。删除静态或自动对象是未定义的行为 - 以及除new之外的任何其他来源可能获得的行为。

答案 1 :(得分:0)

您谈论使用shared pointer。如果该删除是pObj上的最后一次删除,则可能是该对象被删除的最后一次..因此共享指针指向的对象最终将被销毁。在这种情况下,调用pObj的destructor,也许你从那里得到Seg Fault。

另一方面,根据Poco lib使用的共享指针的实现,可能是你通过调用delete来滥用共享指针。

答案 2 :(得分:0)

正如其他人所说,这不是因为你的指针看起来像“0x8fcbed8好”,它是一个正确的指针。

实际上,如果使用“delete”,指针将保持其值。但是你不应该再使用它了。 (在删除后将它设置为NULL是一个很好的做法,因此它与调试器一起显示为“空”。)

如果您使用linux进行开发,有一个工具可以帮助您找到问题所在。这是 valgrind

valgrind  your_program  [args]

(只需在你通常启动的命令前添加“valgrind”。如果还没有在这里安装valgrind,必须在你的发行版上有一个数据包,因为它是一个广泛使用的工具。)

然后valgrind将在程序运行时检查你的程序(稍微放慢一下)并在你删除不应该删除的内容时立即报告。 (还有很多其他错误)

答案 3 :(得分:0)

这是一个非常困难的问题,我不明白问题,但我试着解释它和我的解决方案。 问题是特定于平台的,并且仅在使用带有Poco库的gcc 4.5.5编译器的Gentoo linux上发生。

我有守护进程,它使用模块(插件)来处理不同的请求。模块和守护程序使用一个使用poco库的静态库。在静态库中有代码来创建SSL连接,因此创建SSL管理器。静态库链接到模块和deamon。

在工作结束后,我有一个在我的问题中描述的分段错误。我将静态库更改为共享库,问题消失了,没有seg错误。一切正常。

真的,我不明白,但似乎是gentoo上的gcc编译器bug。在其他Linux上与其他gcc一起使用静态库很好。