set_new_handler and errno

3
如果您使用set_new_handler并且调用了您的处理程序函数,那么errno是否保证像从malloc的返回值0一样设置?还是更好地使用strerror(ENOMEM)errno适用于Microsoft C++和GCC,但这仍然需要保证。

2
这在很大程度上取决于标准库的实现。通常情况下,只有在系统函数调用失败后,errno 才有效,在不知道系统 new 函数中进行了哪些调用的情况下,就无法知道 errno 是否有效。 - Some programmer dude
3
请注意,标准C或标准C++中未定义ENOMEM。因此,答案不会在C++标准中找到,这更像是一个Posix/Windows问题。[编辑:我有些错误,ENOMEM在C++11中定义,但标准除了在errno值列表中提到外,并未详细介绍它] - Steve Jessop
2个回答

2

并没有要求new(或malloc)设置errno。两者都有明确定义的错误报告语义(抛出std::bad_alloc或返回空指针),这与errno无关。(从实现质量的角度来看,我不希望newmalloc被允许修改errno。尽管Posix要求如此。)


2
我认为errno不能很好地检测动态内存分配失败。查看N3337,特别是3.7.4.1节“分配函数”:
2.即使请求的空间大小为零,请求也可能失败。如果请求成功,则返回的值应该是一个非空指针值(4.10)p0,与以前返回的任何值p1都不同,除非该值p1随后被传递给operator delete。对于返回零大小请求的指针进行解引用的效果是未定义的。
3.分配存储空间失败的分配函数可以调用当前安装的new-handler函数(18.6.2.3),如果有的话。[注意:程序提供的分配函数可以使用std :: get_new_handler函数(18.6.2.4)获取当前安装的new_handler的地址。-end note]如果声明具有非抛出异常规范(15.4)的分配函数无法分配存储空间,则应返回空指针。任何其他无法分配存储空间的分配函数只能通过抛出与类型相匹配的处理程序(15.3)的异常来指示失败std :: bad_alloc(18.6.2.1)。
脚注35(仅为指示性和非规范性):
意图是通过调用std :: malloc()或std :: calloc()来实现operator new(),因此规则基本相同。 C ++与C不同之处在于要求零请求返回非空指针。
现在,看一下C标准草案N1570和的7.5错误:
3.初始线程中errno的值在程序启动时为零(其他线程中errno的初始值为不确定值),但是任何库函数都不会将其设置为零。202)无论是否存在错误,库函数调用可能将errno的值设置为非零,前提是在此国际标准的函数描述中未记录使用errno。
似乎可以通过malloc失败来设置errno,但这并非必需。
此外,来自N1570的7.22.3内存管理函数没有指定需要设置errno的malloc或friends。
我的建议是坚持标准保证并使用由new引发的异常(std :: bad_alloc)(即不使用no-throw new)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接