2009-02-05 104 views
10

我有一个Linux C++应用程序,我想在取消引用前测试对象指针的有效性。但是,由于分段错误,try/catch在Linux上不适用。如何才能做到这一点?尝试/捕捉Linux上的段错误

回答

8

如果您有一个应用中的许多指针引用相同的有限生命周期对象的情况,一种流行的解决方案是使用boost smart pointers编辑:在C++ 11,这两种类型的标准库中提供

您可能需要使用shared_ptr为指针(S)是负责你的对象和weak_ptr为其他指针的寿命,这可能会失效。您会看到weak_ptr具有您要求内置的有效性检查。

4

将指针初始化为NULL。如果经过一些处理,它仍然是NULL,它是无效的,否则它是有效的。

+0

如果删除的对象是指针不是NULL,而是指向无效的内存。我如何验证这样的指针? – jackhab 2009-02-05 09:49:09

+1

为什么你会这么想?你删除了它。如果你在任何地方使用指针,并且你不确定它们是否被删除,那么你正在做一些非常错误的事情。 – Bombe 2009-02-05 09:50:30

+0

我其次。无效指针是无效指针。之后,指针变量不再可用,或者将其设置为0.或者,因为这是C++,请了解RAII。 – gimpf 2009-02-05 10:45:13

4

对于这一次发生,您可以为SIGSEGV启用信号处理程序。详细信息请参见手册页“信号”。另一种选择是使用保证有效的引用。这取决于你的应用程序。

+0

手册页说,如果忽略SIGSEGV,则进程状态是未定义的。捕获SIGSEGV后可以恢复C++应用程序吗? – jackhab 2009-02-05 09:55:22

8

分段错误不是异常(如Java的NullPointerException);它是从OS发送到进程的信号。查看the manpage for sigaction以获取有关如何安装分段故障处理程序(SIGSEGV)的指示信息。

1

你如何测试指针的有效性?比较NULL?

你所做的最好的事情是在Valgrind下运行你的程序。一个错误可能在一个完全不同的地方。

更新:在Win32平台上有一些像__try __except,它允许捕捉一些异常。据我所知,该Win32功能没有与Linux相当的功能。

0

如果您将处理程序附加到SIGSEGV,除了记录错误发生和优雅失败的事实之外,您可以做的事情并不多。发生此违规时,您的程序处于未定义状态,因此可能不安全以继续正常操作。

除了检查NULL之外,我不认为有一种方法可以检查指针是否在您描述的意义上是“有效”的。在正常操作过程中,像这样的错误不应该发生,因为它们代表一个错误,所以你应该希望程序失败,尽管优雅。

0

指针存储在对象中。它们在构造函数中初始化,可能为0(NULL)。它们在析构函数中被删除,可能在赋值中,很少在其他函数中被删除。当在析构函数以外的成员中被删除时,它们立即被分配一个新的值或0.

2

没有自然的,通用的原始C++指针。 C++假定你会跟踪这些信息。

在大多数情况下,您可以通过记住在无效时将指针设置为NULL来处理此问题。最初不指向的新指针应该设置为NULL,并且新删除的对象应将其指针设置为NULL。