c++ - Hinnant 的堆栈分配器和异常

标签 c++ exception heap-memory allocation stack-memory

我想将 Hinnant 的堆栈分配器(documentationimplementation)与 STL 容器结合使用,但我想对其进行修改,以便永远不会进行动态内存分配

要实现这一点,必须做的一件事是替换分配/解除分配方法中的新/删除调用,如果堆栈提供的缓冲区上没有空间,则会发生这些调用。

但是我应该如何处理异常呢? STL 容器可能会抛出异常,例如

std::vector::at

"The function automatically checks whether n is within the bounds of valid elements in the vector, throwing an out_of_range exception if it is not [...]"

http://www.cplusplus.com/reference/vector/vector/at/

异常是存储在动态内存还是静态内存中,我找不到明确的答案。只有这些行给出提示:

From [except.throw]/15.1/4:

The memory for the exception object is allocated in an unspecified way, except as noted in 3.7.4.1.

The final reference, [basic.stc.dynamic.allocation]/4, says:

[Note: In particular, a global allocation function is not called to allocate storage for [...] an exception object (15.1). — end note]

https://stackoverflow.com/a/27259902/8007684

这到底是什么意思?为异常预留的内存是否放在静态内存中?或者是否仍然有任何分配以“未指定的方式”发生,这意味着异常将被动态存储?引用的描述有很大的解释空间......

所以我的基本问题是:如果禁止使用动态内存,使用 STL 容器+Hinnant 的堆栈分配器是否安全?或者这不起作用,我要么必须使用 -fno-exceptions 来通过 abort() 调用替换异常,要么实现我自己的不抛出异常的 STL 容器替换...?

提前致谢!

启发

最佳答案

gcc 和 clang 实现遵循称为 Itanium ABI 的规范.它说,除其他外:

Storage is needed for exceptions being thrown. This storage must persist while stack is being unwound, since it will be used by the handler, and must be thread-safe. Exception object storage will therefore normally be allocated in the heap, although implementations may provide an emergency buffer to support throwing bad_alloc exceptions under low memory conditions (see Section 3.3.1).

Memory will be allocated by the __cxa_allocate_exception runtime library routine. This routine is passed the size of the exception object to be thrown (not including the size of the __cxa_exception header), and returns a pointer to the temporary space for the exception object. It will allocate the exception memory on the heap if possible. If heap allocation fails, an implementation may use other backup mechanisms (see Section 3.4.1).

If __cxa_allocate_exception cannot allocate an exception object under these constraints, it calls terminate().

__cxa_allocate_exception 的 libc++abi 实现是 here .它将首先进入堆,如果失败,尝试在 libc++abi.dylib 中静态分配的紧急备份缓冲区。如果堆和紧急存储都无法为任意大小的用户创建的异常分配足够的内存,则调用 terminate()

关于c++ - Hinnant 的堆栈分配器和异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50640960/

相关文章:

c++ - 如何通过链表将最大大小为 20 添加到堆栈

python - 在 Django 中使用大量的 try... except 来记录每个错误

c++ - 在有限递归循环中操作大型数组时,我应该从堆栈切换到堆的什么点?

c - 在 C 中释放动态分配的二维数组

c++ - 英特尔 SGX 错误 : What does the 8207 error mean when I cannot load the enclave correct

c++ - 将 SetSysColor 限制为一个应用程序

python - 我怎样才能做到这一点?我应该使用 requests 还是 urllib.error 来处理异常?

java - 当获取设置了超时的 Future 结果时,哪里抛出了异常?

symbian - 如何使用 J2ME API 在诺基亚手机的 J2ME 应用程序中触发 Symbian C++ 应用程序?

c++ - 从 Winlogon 桌面切换到用户桌面