新算子异常安全
Exception safety of new operator
这是 libstdc++ 中新运算符的implementation:
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (__builtin_expect (sz == 0, false))
sz = 1;
while ((p = malloc (sz)) == 0)
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
return p;
}
谁保证构造函数中的异常会释放分配的内存?
更新:感谢评论员——实际上我的意思是新表达式的异常安全。
您在问题中混淆了“新表达式”和“新运算符”。
新表达式是这样的:A* a = new A();
C++ 语言定义,这个表达式被评估为这样的东西(过度简化的伪代码):
void* __a = operator new(sizeof(A));
try {
A::A(this = static_cast<A*>(__a));
} catch (...) { operator delete (__a); throw; }
如您所见 - 如果发生异常,内存将被释放。
更详细explanation:
If initialization terminates by throwing an exception (e.g. from the
constructor), if new-expression allocated any storage, it calls the
appropriate deallocation function: operator delete for non-array type,
operator delete[] for array type.
对于编译器生成的真实代码 - 请参阅 here。
您可能会注意到对 operator delete 的调用 - 即使源代码不包含它:
struct A { A(); };
A::A() { throw 13; }
int main()
{
auto a = new A();
}
汇编程序:
call 401040 <operator new(unsigned long)@plt>
...
call 401172 <A::A()>
...
call 401050 <operator delete(void*, unsigned long)@plt>
...
call 401080 <_Unwind_Resume@plt>
这是 libstdc++ 中新运算符的implementation:
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (__builtin_expect (sz == 0, false))
sz = 1;
while ((p = malloc (sz)) == 0)
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
return p;
}
谁保证构造函数中的异常会释放分配的内存?
更新:感谢评论员——实际上我的意思是新表达式的异常安全。
您在问题中混淆了“新表达式”和“新运算符”。
新表达式是这样的:A* a = new A();
C++ 语言定义,这个表达式被评估为这样的东西(过度简化的伪代码):
void* __a = operator new(sizeof(A));
try {
A::A(this = static_cast<A*>(__a));
} catch (...) { operator delete (__a); throw; }
如您所见 - 如果发生异常,内存将被释放。
更详细explanation:
If initialization terminates by throwing an exception (e.g. from the constructor), if new-expression allocated any storage, it calls the appropriate deallocation function: operator delete for non-array type, operator delete[] for array type.
对于编译器生成的真实代码 - 请参阅 here。 您可能会注意到对 operator delete 的调用 - 即使源代码不包含它:
struct A { A(); };
A::A() { throw 13; }
int main()
{
auto a = new A();
}
汇编程序:
call 401040 <operator new(unsigned long)@plt>
...
call 401172 <A::A()>
...
call 401050 <operator delete(void*, unsigned long)@plt>
...
call 401080 <_Unwind_Resume@plt>