当委托构造函数抛出时,内存是否自动回收? [英] Is the memory automatically reclaimed when a delegating constructor throws?
问题描述
接下来:委托构造函数抛出时调用析构函数?
class X
{
public:
X(){};
X(int):X(){throw std :: exception(); }
X(double){throw std :: exception(); }
〜X();
};
动态内存怎么办?通常,构造函数中的异常意味着对象没有被完全构造,因此内存被清理并且不会丢失。
但前面问题中的参数是对象是在代理完成后完全构建(或完全初始化)。这如何影响回收内存?我希望内存仍然清理!
int main()
{
new X(5) // new called
//删除调用因为委托完成。
//我假设:
//内存重新声明(因为构造函数没有完成)
//我假设调整了C ++ 11标准来补偿。
//作为构造函数完成。
}
比较:
int main()
{
new X(5.0); // new called
//删除** NOT **调用
//内存已重新声明(因为构造函数没有完成)
}
如果内存被清除,那么内存清理的定义需要从C ++ 03 spec。 c> $ 如果由 如果上述对象初始化的任何部分 76 可以找到异常和合适的解除分配函数,调用解除分配函数释放正在构建对象的内存。 >— C ++ 11 [expr.new] 5.3.4 / 18 对象初始化的任何部分描述包括构造函数调用和传递给构造函数的表达式的计算。 此外,这个行为在C ++ 98标准中有相同的规定[C ++ 98 5.4.3 / 17]。委托构造函数唯一的区别是,如果你的心理模型以前是基于完全构造的对象。 在第一个例子中: 事件顺序为: 使用第二个示例 您可以通过替换分配和释放函数来观察此行为: 此程式的正确输出为: Following on from this: Is the destructor called when a delegating constructor throws? What about dynamic memory? Normally an exception in the constructor means the object was not fully constructed and thus the memory is cleanedup and not lost. But the argument in the previous question is that the object is fully constructed (or fully initialized) after the delegate completes. How does this affect reclaiming the memory? I would hope that memory is still cleanedup! Compared too: If the memory is cleaned up, then the definition of when the memory is cleanup needs to be altered from C++03 spec. How is the behavior changed? If the constructor called by If any part of the object initialization described above76 terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed — C++11 [expr.new] 5.3.4/18 The 'any part of the object initialization' described includes both the constructor calls and evaluation of the expressions passed to the constructor. Also, this behavior is specified identically in the C++98 standard [C++98 5.4.3/17]. The only difference delegating constructors make is if your mental model was previously based on the object being completely constructed or not. Given delegating constructors that's no longer equivalent to the actual specification of when deallocation occurs. In your first example: The order of events is: With the second example
You can observe this behavior by replacing the allocation and deallocation functions: The correct output of this program is:
这篇关于当委托构造函数抛出时,内存是否自动回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
new
调用的构造函数抛出一个异常,那么由 new
分配的内存将被自动释放。
new X(5);
new X(5.0);
#include< iostream>
#include< cstdlib>
#include< stdexcept>
#include< new>
void * operator new(std :: size_t s){
if(void * ptr = std :: malloc(s)){
std :: cout< ; allocation\\\
;
return ptr;
}
throw std :: bad_alloc {};
}
void operator delete(void * ptr)noexcept {
if(ptr){
std :: cout< deallocation\\\
;
std :: free(ptr);
}
}
struct S {
S(){};
S(int):S {} {throw std :: exception(); }
S(double){throw std :: exception(); }
〜S(){std :: cout<< destructor\ n; }
};
int main(){
std :: cout< test 1 \\\
;
try {
new S(1);
} catch(...){
std :: cout< exception caught\\\
;
}
std :: cout<< test 2\\\
;
try {
new S(1。);
} catch(...){
std :: cout< exception caught\\\
;
}
}
test 1
分配
destructor
deallocation
捕获到异常
test 2
分配
deallocation
捕获异常
class X
{
public:
X() {};
X(int) : X() { throw std::exception(); }
X(double) { throw std::exception(); }
~X();
};
int main()
{
new X(5); // new called
// delete called because delegate completed.
// I assume:
// Memory re-claimed (because constructor did not complete)
// I assume the C++11 standard adjusted to compensate.
// As a constructor did complete.
}
int main()
{
new X(5.0); // new called
// Delete **NOT** called
// Memory re-claimed (because constructor did not complete)
}
new
throws an exception then the memory allocated by new
is automatically deallocated. Delegating constructors change nothing in this regard.
new X(5);
new X(5.0);
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <new>
void *operator new(std::size_t s) {
if (void *ptr = std::malloc(s)) {
std::cout << "allocation\n";
return ptr;
}
throw std::bad_alloc{};
}
void operator delete(void *ptr) noexcept {
if (ptr) {
std::cout << "deallocation\n";
std::free(ptr);
}
}
struct S {
S() {};
S(int) : S{} { throw std::exception(); }
S(double) { throw std::exception(); }
~S() { std::cout << "destructor\n"; }
};
int main() {
std::cout << "test 1\n";
try {
new S(1);
} catch(...) {
std::cout << "exception caught\n";
}
std::cout << "test 2\n";
try {
new S(1.);
} catch(...) {
std::cout << "exception caught\n";
}
}
test 1
allocation
destructor
deallocation
exception caught
test 2
allocation
deallocation
exception caught