Hinnant的堆栈分配器和异常

时间:2018-06-01 10:02:42

标签: c++ exception stack heap allocation

我想将Hinnant的堆栈分配器(documentationimplementation)与STL容器结合使用,但我想修改它,以便动态内存分配永远不会发生< / strong>即可。

要实现这一点,必须做的一件事是,如果堆栈提供的缓冲区没有空间,则替换allocate / deallocate方法中的new / delete调用。

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

  

的std ::矢量::在

     

&#34;该函数自动检查n是否在范围内   向量中的有效元素,如果它,则抛出out_of_range异常   不是[...]&#34;

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

我无法找到动态或静态内存中存储异常的明确答案。只有这些行给出了提示:

  

来自[except.throw] /15.1/4:

     

异常对象的内存以未指定的方式分配   方式,除了3.7.4.1中所述。

     

最终参考文献[basic.stc.dynamic.allocation] / 4表示:

     

[注意:特别是,不调用全局分配函数   为[...]异常对象分配存储空间(15.1)。 - 结束说明]

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

这究竟是什么意思?是否为静态内存中的异常保留了内存?或者仍有任何分配以未指明的方式发生&#34;这意味着将动态存储异常?引用的描述为解释带来了很大的空间......

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

提前致谢!

激发

1 个答案:

答案 0 :(得分:4)

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

  

抛出异常需要存储。这个存储必须在堆栈被解除时保持不变,因为它将由处理程序使用,并且必须是线程安全的。因此,异常对象存储通常会在堆中分配,尽管实现可能会提供紧急缓冲区以支持在低内存条件下抛出bad_alloc异常(参见第3.3.1节)。

     

内存将由__cxa_allocate_exception运行时库例程分配。此例程传递要抛出的异常对象的大小(不包括__cxa_exception标头的大小),并返回指向异常对象的临时空间的指针。如果可能的话,它将在堆上分配异常内存。如果堆分配失败,则实现可以使用其他备份机制(参见第3.4.1节)。

     

如果__cxa_allocate_exception无法在这些约束下分配异常对象,则会调用terminate()

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