ins*_*ire 5 c++ heap stack allocation exception
我想将Hinnant的堆栈分配器(文档,实现)与STL容器结合使用,但我想修改它,以便永远不会发生动态内存分配.
要实现这一点,必须要做的一件事是,如果堆栈提供的缓冲区中没有空间,则替换allocate/deallocate方法中的new/delete调用.
但是我应该如何处理异常呢?STL容器可能会抛出异常,例如
的std ::矢量::在
"该函数自动检查n是否在向量中的有效元素范围内,如果不是[...]则抛出out_of_range异常"
http://www.cplusplus.com/reference/vector/vector/at/
我无法找到动态或静态内存中存储异常的明确答案.只有这些行给出提示:
从[except.throw] /15.1/4开始:
除非在3.7.4.1中指出,否则异常对象的内存以未指定的方式分配.
最后的参考文献[basic.stc.dynamic.allocation]/4表示:
[注意:特别是,不会调用全局分配函数来为异常对象(15.1)分配存储空间. - 结束说明]
这到底是什么意思?是否为静态内存中的异常保留了内存?或者是否仍然以"未指定的方式"发生任何分配,这意味着将动态存储异常?引用的描述为解释带来了很大的空间......
所以我的基本问题是:如果禁止动态内存使用,使用STL容器+ Hinnant的堆栈分配器是否安全?或者这不起作用,我要么必须使用-fno-exceptions通过abort()调用替换异常或实现我自己的STL容器的替换,不抛出异常......?
提前致谢!
启发
gcc 和 clang 实现遵循称为Itanium ABI的规范。它说,除其他外:
抛出异常需要存储。该存储在堆栈展开时必须持续存在,因为它将被处理程序使用,并且必须是线程安全的。因此,异常对象存储通常会在堆中分配,尽管实现可能会提供紧急缓冲区以支持
bad_alloc在内存不足的情况下抛出异常(请参阅第 3.3.1 节)。内存将由
__cxa_allocate_exception运行时库例程分配。该例程传递要抛出的异常对象的大小(不包括__cxa_exception头的大小),并返回一个指向异常对象临时空间的指针。如果可能,它将在堆上分配异常内存。如果堆分配失败,实现可能会使用其他备份机制(参见第 3.4.1 节)。如果
__cxa_allocate_exception无法在这些约束下分配异常对象,则调用terminate().
libc中++ ABI执行的__cxa_allocate_exception是在这里。它将首先进入堆,如果失败,请尝试在 libc++abi.dylib 中静态分配的紧急备份缓冲区。如果堆和紧急存储都未能为任意大小的用户创建的异常分配足够的内存,terminate()则调用。
| 归档时间: |
|
| 查看次数: |
222 次 |
| 最近记录: |