对于第一个问题:当new
操作是由编译器遇到喜欢在你的榜样:
int * pData = new int[256];
它有效地生成代码,看起来像这样:
int *pData = reinterpret_cast<int*>(::operator new(256 * sizeof(int)));
// the compiler may also choose to reserve extra space here or elsewhere to
// "remember" how many elements were allocated by this new[] so delete[]
// can properly call all the destructors too!
如果构造函数应该被调用,也会被释放(在这个例子中,没有构造函数被称为我相信)。
operator new(std::size_t)
是由标准库实现的,经常,但并不总是,它会归结为一个malloc
通话功能。
malloc
将不得不作出一个system call,从OS请求内存。由于操作系统分配器通常使用更大的固定大小的内存块,因此只有当它耗尽了当前拥有的内存时,malloc
才会每次都进行此调用。
对于第二个问题:对于局部变量,它真的是由编译器。该标准没有提到堆栈。但是,很可能您使用的是运行通用操作系统并使用通用编译器的通用体系结构:-)。
所以对于共同情况下,编译器将典型地通过相应地调节叠层,或者如果它可以(寄存器是因为优选的选择保留的寄存器为它们保留在该函数调用的所有的局部变量的开头空间这是多更快)。
然后(在C++中),当遇到变量时,它会调用构造函数。理论上讲,可以根据需要调整堆栈,但这会证明是正确的并且效率较低。通常,预留堆栈空间是单个指令,因此一次完成所有操作都非常理想。
对于简单类型int(或者几乎任何类型,作为一个简单的析构函数),该规则仍然适用,但优化通常仍然可以完成,因为“as if”规则。一个不能优化的例子就像'{int z = 42; foo(&z); bar(); baz();}',其中编译器无法看到foo bar和baz的实现(例如,因为它们是系统调用),那么编译器必须假定bar或baz可以访问z,因此在baz返回之前,不能重新使用分配给z的空间 – 2011-04-05 00:58:08