关于operator new的一些理解,算是重读《Effective C++》有感
1. operator new的实现
# in gcc/libstdc++-v3/libsupc++/new_op.cc
....
#include <bits/c++config.h>
#include <cstdlib>
#include <bits/exception_defines.h>
#include "new"
using std::new_handler;
using std::bad_alloc;
#if _GLIBCXX_HOSTED
using std::malloc;
#else
// A freestanding C runtime may not provide "malloc" -- but there is no
// other reasonable way to implement "operator new".
extern "C" void *malloc (std::size_t);
#endif
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
while (__builtin_expect ((p = malloc (sz)) == 0, false))
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
return p;
}
2. 我们看到并需要理解的
2.1 handler函数是循环调用的
如果malloc没有成功,handler函数会循环调用,除非我们将handler设置为空,或者在handler中抛出异常。这样我们再去看条款49也就比较好理解了。
3. placement new
如果operator new接受的参数除了一定会有的那个size_t之外,还有其他的参数,这便是所谓的placement new。
# in gcc/libstdc++-v3/libsupc++/new
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
说到placement new,最先想到的就是上面这个版本,输入一个内存区域指针。看到实现发现,如此简单,就直接返回了。
3.1 placement new / delete
如果实现了placement new,则需要实现对应的placement delete。因为如果类构造函数出异常了,c++内部会调用对应的placement delete。
4. 关于构造函数和析构函数出问题需要怎么处理
参考:https://isocpp.org/wiki/faq/exceptions#ctors-can-throw
在构造函数中,抛出异常;在析构函数中,中断程序。