3

如果你使用set_new_handler并且你的处理函数被调用,errno保证被设置,它是从 0 返回的方式malloc?还是更好用strerror(ENOMEM)errno适用于 Microsoft C++ 和 GCC,但这仍然存在是否得到保证的问题。

4

2 回答 2

2

没有要求new(或malloc就此而言)设置errno. 两者都有明确定义的错误报告语义(抛出std::bad_alloc或返回空指针),不涉及errno. (从实施质量的角度来看,我不希望new或被malloc允许修改errno。不符合 Posix 要求。)

于 2012-06-14T12:49:35.880 回答
2

我认为errno检测动态内存分配失败还不够好。查看 N3337,特别是3.7.4.1 分配功能

2 [...] 即使请求的空间大小为零,请求也可能失败。如果请求成功,则返回的值应是一个非空指针值 (4.10) p0,不同于任何先前返回的值 p1,除非该值 p1 随后被传递给操作员删除。取消引用作为零大小请求返回的指针的效果是未定义的。35

3分配存储失败的分配函数可以调用当前安装的新处理函数 (18.6.2.3),如果有的话。[ 注意:程序提供的分配函数可以使用 std::get_new_handler 函数 (18.6.2.4) 获取当前安装的 new_handler 的地址。—尾注]如果使用非抛出异常规范(15.4)声明的分配函数未能分配存储,它应返回一个空指针。任何其他分配存储失败的分配函数只能通过抛出与 std::bad_alloc (18.6.2.1) 类型的处理程序 (15.3) 匹配的类型的异常来指示失败。

和脚注 35(这只是指示性和非规范性的):

35)意图是通过调用 std::malloc() 或 std::calloc() 使 operator new() 可实现,因此规则基本相同。C++ 与 C 的不同之处在于要求零请求以返回非空指针。

现在,前往 C 标准草案 N1570 并查看7.5 错误<errno.h>

3程序启动时初始线程中errno的值为零(其他线程中errno的初始值为不确定值),但绝不会被任何库函数设置为零。202)errno的值可以设置为如果在本国际标准的函数描述中未记录 errno 的使用,则无论是否存在错误,库函数调用都为非零。

似乎errno可能由malloc失败设置,但这不是必需的。

另外N1570的7.22.3内存管理功能也没有规定malloc或者朋友需要设置errno

我的建议是坚持标准保证并使用std::bad_alloc抛出的异常 ( ) new(即不使用 no-throw new)。

于 2012-06-14T12:50:14.340 回答