ACE服务端编程系列的第三篇,探究ACE解决不同编译器之间分配堆内存的差异。
在ACE的官方示例中会看到大量的ACE_NEW_RETURN,ACE_NEW这样的宏,这是ACE为了消除不同编译器编译的代码在堆上分配内存失败的行为差异。
具体来说:
使用 malloc/calloc 等分配内存的函数时,一定要检查其返回值是否为“空指针”(亦即检查分配内存的操作是否成功),这是良好的C++编程习惯,也是编写可靠服务端程序所必需的。
如果使用 new 分配内存失败时,C++标准的规定是抛出异常,如果想检查内存分配是否成功,应该捕捉异常。而一些老的编译器里,new 如果分配内存失败,是不抛出异常的,因为那时 C++ 还没加入异常机制和制定标准。
为了消除这种不一致性,ACE提供了三个宏,在内存分配失败时采用了malloc的方式,设置为空指针:
ACE_NEW(p,c):使用构造器c分配内存,在失败时p设置为0,并执行return;
ACE_NEW_RETURN(p,c,r):使用构造器c分配内存,在失败时p设置为0,并执行return r;
ACE_NEW_NORETURN(p,c):使用构造器c分配内存,在失败时p设置为0,并执行下一条语句;
示例代码:
ACE_NEW_RETURN (http_url, HTTP_URL (**url_addr_ptr), 0); ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof(Message)), -1); char *c; ACE_NEW_NORETURN(c,char [64]); if(c == 0){ exit(1) }
更深一层,如果发生堆内存分配失败,实际上更应该考虑系统中是否存在严重的内存泄露,而且基本的现代C++编译器都遵循了标准抛出异常,对于是否使用ACE的这三个宏大家可以自己选择。
延伸阅读: