gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:32:48 25 4
gpt4 key购买 nike

我想将 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com