c++ - 当我 `throw` 某事时,它存储在内存中的什么位置?

标签 c++ exception exception-handling

我知道当某些东西是 thrown 时,堆栈会“展开”到它被捕获的点,并且每个函数上下文中堆栈上的类实例的析构函数都会运行(其中这就是为什么你不应该从析构函数中抛出异常 - 你最终可能会抛出第二个异常)......但我想知道在这种情况发生时我抛出的对象存储在内存中的哪个位置?

它是否依赖于实现?如果是这样,是否有最流行的编译器使用的特定方法?

最佳答案

是的,答案取决于编译器。

对我的编译器 (g++ 4.4.3) 的快速实验表明,它的运行时库首先尝试 malloc 内存以查找异常,如果失败,则尝试分配位于数据段上的进程范围的“紧急缓冲区”中的空间。如果这不起作用,它会调用 std::terminate()

似乎紧急缓冲区的主要目的是能够在进程用完堆空间后抛出 std::bad_alloc(在这种情况下 malloc 调用会失败)。

相关函数为__cxa_allocate_exception :

extern "C" void *
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
{
  void *ret;

  thrown_size += sizeof (__cxa_refcounted_exception);
  ret = malloc (thrown_size);

  if (! ret)
    {
      __gnu_cxx::__scoped_lock sentry(emergency_mutex);

      bitmask_type used = emergency_used;
      unsigned int which = 0;

      if (thrown_size > EMERGENCY_OBJ_SIZE)
        goto failed;
      while (used & 1)
        {
          used >>= 1;
          if (++which >= EMERGENCY_OBJ_COUNT)
            goto failed;
        }

      emergency_used |= (bitmask_type)1 << which;
      ret = &emergency_buffer[which][0];

    failed:;

      if (!ret)
        std::terminate ();
    }

  // We have an uncaught exception as soon as we allocate memory.  This
  // yields uncaught_exception() true during the copy-constructor that
  // initializes the exception object.  See Issue 475.
  __cxa_eh_globals *globals = __cxa_get_globals ();
  globals->uncaughtExceptions += 1;

  memset (ret, 0, sizeof (__cxa_refcounted_exception));

  return (void *)((char *)ret + sizeof (__cxa_refcounted_exception));
}

我不知道这个方案有多典型。

关于c++ - 当我 `throw` 某事时,它存储在内存中的什么位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6611880/

相关文章:

iPhone SDK/iOS 在 webview/scrollview 中崩溃?

java - Java SE7 中的异常抑制

c++ - 将引用 qplaintextedit 发送到 C++ 构造函数类

引用数组中对象的 C++ 共享指针

c++ - 当我的编译器不符合标准时如何将数组成员归零

PHP - 无法捕获 Google API 库抛出的异常

java - 使用类对象作为泛型类型

c++ - 将 C++ 输入与数组值进行比较

C# 如果捕获到异常,它会到达我的返回语句吗?

python - 在 Python 中获取异常值