C++ 运算符 new 将内存初始化为零
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7546620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Operator new initializes memory to zero
提问by scdmb
There is such code:
有这样一段代码:
#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;
}
Result:
结果:
wsk2: 0x928e008 5
wsk2: 0x928e008 0
I have read that new
doesn't initialize memory with zeroes. But here it seems that it does. How does it work?
我读过new
不会用零初始化内存。但在这里似乎确实如此。它是如何工作的?
回答by Martin York
There are two versions:
有两个版本:
wsk = new unsigned int; // default initialized (ie nothing happens)
wsk = new unsigned int(); // zero initialized (ie set to 0)
Also works for arrays:
也适用于数组:
wsa = new unsigned int[5]; // default initialized (ie nothing happens)
wsa = new unsigned int[5](); // zero initialized (ie all elements set to 0)
In answer to comment below.
回答下面的评论。
Ehm... are you sure that
new unsigned int[5]()
zeroes the integers?
嗯...你确定
new unsigned int[5]()
将整数归零吗?
Apparently yes:
显然是的:
[C++11: 5.3.4/15]: A new-expression that creates an object of type T initializes that object as follows: If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed, the object has indeterminate value. Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.
[C++11: 5.3.4/15]:创建 T 类型对象的 new 表达式如下初始化该对象:如果省略 new-initializer,则对象默认初始化 (8.5);如果未执行初始化,则对象具有不确定的值。否则,new-initializer 将根据 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";
}
Results:
结果:
> 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
>
回答by CB Bailey
operator new
is not guaranteed to initialize memory to anything, and the new-expressionthat allocates an unsigned int
without a new-initializerleaves the object with an indeterminate value.
operator new
不能保证将内存初始化为任何东西,并且分配 an的new 表达式unsigned int
没有新的初始化器,会给对象留下一个不确定的值。
Reading the value of an uninitialized object results in undefined behavior. Undefined behaviorincludes evaluating to the value zero with no ill effects but could result in anything happening so you should avoid causing it.
读取未初始化对象的值会导致未定义行为。未定义的行为包括计算为零值而没有不良影响,但可能会导致任何事情发生,因此您应该避免导致它。
In C++11, the language used is that the allocated objects are default-initializedwhich for non-class types means that no initialization is performed. This is different from the meaning of default-initializedin C++03.
在 C++11 中,使用的语言是分配的对象是默认初始化的,对于非类类型意味着不执行初始化。这与C++03中default-initialized的含义不同。
回答by Michael J
With some compilers, the debug version of new will initialise the data, but there is certainly nothing that you can rely on.
对于某些编译器,调试版本的 new 会初始化数据,但肯定没有什么可以依赖的。
It is also possible that the memory just had 0 from a previous use. Don't assume that nothing happened to the memory between delete and new. There could be something done in the background that you never noticed. Also, the same pointer value might not be the same physical memory. Memory pages get moved and paged out and in. A pointer might be mapped to an entirely different location than earlier.
也有可能内存从上次使用中只有 0。不要假设 delete 和 new 之间的内存没有发生任何事情。可能在后台做了一些你从未注意到的事情。此外,相同的指针值可能不是相同的物理内存。内存页被移出和调入。一个指针可能被映射到一个与之前完全不同的位置。
Bottom line: if you didn't specifically initialise a memory location then you can assume nothing about its contents. The memory manager might not even allocate a specific physical memory location until you use the memory.
底线:如果你没有专门初始化一个内存位置,那么你就不能假设它的内容。在您使用内存之前,内存管理器甚至可能不会分配特定的物理内存位置。
Modern memory management is amazingly complex, but as a C++ programmer you don't really care (mostly?). Play by the rules and you won't get into trouble.
现代内存管理非常复杂,但作为 C++ 程序员,您并不真正关心(主要是?)。遵守规则,你就不会惹上麻烦。
? You might care if you are optimising to reduce page faults.
? 您可能会关心是否正在优化以减少页面错误。
回答by Ernest Friedman-Hill
That's not operator new
, that's the new
operator. There's actually a big difference! The difference is that operator new
is a function that returns raw memory; when you use the new
operator, it invokes a constructor for you. It's the constructor that's setting the value of that int
, not operator new
.
那不是operator new
,那是new
运营商。其实差别很大!不同之处在于它operator new
是一个返回原始内存的函数;当您使用new
运算符时,它会为您调用构造函数。是构造函数设置了 that 的值,而int
不是operator new
.