操作员将内存初始化为零

有这样的代码:

#include <iostream> int main(){ unsigned int* wsk2 = new unsigned int(5); std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; delete wsk2; wsk2 = new unsigned int; std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl; return 0; } 

结果:

 wsk2: 0x928e008 5 wsk2: 0x928e008 0 

我已经读了new不用零初始化内存。 但是在这里看起来确实如此。 它是如何工作的?

有两个版本:

 wsk = new unsigned int; // default initialized (ie nothing happens) wsk = new unsigned int(); // zero initialized (ie set to 0) 

也适用于数组:

 wsa = new unsigned int[5]; // default initialized (ie nothing happens) wsa = new unsigned int[5](); // zero initialized (ie all elements set to 0) 

回答下面的评论。

呃…你确定新的unsigned int5是整数吗?

显然是的:

[C ++ 11:5.3.4 / 15]:创buildtypes为T的对象的新expression式将按如下所示初始化该对象:如果省略了新初始化程序,则该对象将被默认初始化(8.5)。 如果没有执行初始化,则该对象具有不确定的值。 否则,按照8.5的初始化规则对新的初始化器进行解释以进行直接初始化。

 #include <new> #include <iostream> int main() { unsigned int wsa[5] = {1,2,3,4,5}; // Use placement new (to use a know piece of memory). // In the way described above. // unsigned int* wsp = new (wsa) unsigned int[5](); std::cout << wsa[0] << "\n"; // If these are zero then it worked as described. std::cout << wsa[1] << "\n"; // If they contain the numbers 1 - 5 then it failed. std::cout << wsa[2] << "\n"; std::cout << wsa[3] << "\n"; std::cout << wsa[4] << "\n"; } 

结果:

 > g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.2.0 Thread model: posix > g++ t.cpp > ./a.out 0 0 0 0 0 > 

operator new不保证将内存初始化为任何内容,并且在没有new-initializer的情况下分配unsigned intnewexpression式将使对象具有不确定的值。

读取未初始化的对象的值会导致未定义的行为未定义的行为包括评估零值,没有不良影响,但可能导致任何事情发生,所以你应该避免造成它。

在C ++ 11中,使用的语言是分配的对象是默认初始化的 ,对于非类types来说,这意味着不执行初始化。 这与C ++ 03中默认初始化的含义不同。

这不是operator newoperator new ,那是new运营商。 其实有一个很大的区别! 不同之处在于operator new是返回原始内存的函数。 当你使用new运算符时,它会为你调用一个构造函数。 这是设置该int的值,而不是operator new的构造函数。

有了一些编译器,new的debugging版本将会初始化数据,但肯定没有什么可以依赖的。

内存也可能是从以前的使用0。 不要以为在删除和新build之间没有任何内存发生。 在背景中可能有一些你从未注意过的东西。 而且,相同的指针值可能不是相同的物理内存。 内存页面被移动并分页input。指针可能被映射到与之前完全不同的位置。

底线:如果你没有专门初始化一个内存位置,那么你可以不假设它的内容。 内存pipe理器可能不会分配一个特定的物理内存位置,直到您使用内存。

现代内存pipe理非常复杂,但作为一名C ++程序员,你并不在意(主要是‡)。 玩规则,你不会陷入困境。

‡如果您正在优化以减less页面错误,您可能会关心。