繁体   English   中英

可以取消对指针的引用吗?

[英]Can dereferencing of pointer throw?

我正在自学使用;)异常安全模式进行编程的技术,并且我想知道解除引用指针是否会引发异常? 我认为这对所有C ++程序员了解保证不会抛出的所有操作会有所帮助,因此,如果有人可以编写这样的列表,我将非常感激。

如果没有指向指针的指定类型的有效对象,则取消引用简单指针T* )可能导致未定义行为 UB的本质是结果可能是任何东西 ,包括但不限于C ++异常。 确实可以想象有一种实现将检查访问指针并抛出异常。 但是,我怀疑这样的C ++实现是否会存在(如果您可以节省这样做的运行时开销,为什么要使用C ++?),并且大多数平台上的常见行为是混淆(如果分配了相关的内存)或崩溃) 在某些平台上,有一些方法可以拦截此类崩溃(例如Windows的“ 结构化异常” )。

但是,一元运算operator*()可能会重载 ,通常用于智能指针和迭代器。 这样的实现当然可以执行其实现者想要的任何事情,包括但不限于引发异常。 但同样由于运行时开销,常见的智能指针实现仅在调试版本中(通常使用某种形式的断言)签入,而在发布版本中则不签入。 (一个值得注意的例外是最近的Visual C ++实现中的迭代器,它确实为这种异常行为带来了很大的麻烦。)

在C ++中,有很强的传统来区分程序员可能避免的错误 (例如,超出范围访问数组)和程序员无法避免的错误 (例如网络连接中断)。 对于原始速度,前者通常会导致UB ,因为每次检查它们都会降低性能。 留给程序员检查是否适当和必要。
您可以在标准库的异常层次结构的定义中看到这种区别,该层次分为可预防的std::logic_errorstd::logic_error预防的std::runtime_error

取消引用无效的指针是未定义的行为,然后实现可以将其定义为引发的异常。 尽管这是某些其他语言中的规则,但在C ++中很少见。

您可以使用std::signal( my_handler, SIGSEGV );捕获内存访问异常std::signal( my_handler, SIGSEGV ); ,尽管这仍然取决于平台支持,并且Standard不允许您将其转换为C ++异常。

我知道Microsoft拥有自己的“托管”异常或某些此类异常,也许可以用该机制捕获并在C ++约定中重新抛出。 也许那是被禁止的; 我不知道。

解除引用发生在运行时,并且级别很低(程序集/机器级别),因此它不能抛出任何东西,但是会引发异常,例如linux / unix上的EXCEPTION_ACCESS_VIOLATION或SegFault。

(这假设正在使用原始指针)

如果它是一个简单的指针(而不是某些自动指针对象或迭代器等),则取消引用的行为将不会引发异常,因为取消引用本身不会执行任何操作。 在编译过程中,取消引用指针只是告诉编译器编写一条使用该指针指向的内容执行指令的方法。 如果指针无效,并且您尝试使用取消引用的表达式对其进行写入,则它肯定会(或应该)出错。

举个例子:

int *p = 0xFFFFFFFF; // Invalid pointer
*p;                  // Dereferenced, but since it doesn't do anything there's no error
*p = 0;              // Dereferenced write, so it will halt and catch fire

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM