scd*_*dmb 66 c++ memory-management
有这样的代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
结果:
wsk2: 0x928e008 5
wsk2: 0x928e008 0
Run Code Online (Sandbox Code Playgroud)
我读过new
没有用零初始化内存.但似乎它确实如此.它是如何工作的?
Mar*_*ork 167
有两个版本:
wsk = new unsigned int; // default initialized (ie nothing happens)
wsk = new unsigned int(); // zero initialized (ie set to 0)
Run Code Online (Sandbox Code Playgroud)
也适用于数组:
wsa = new unsigned int[5]; // default initialized (ie nothing happens)
wsa = new unsigned int[5](); // zero initialized (ie all elements set to 0)
Run Code Online (Sandbox Code Playgroud)
在回答下面的评论.
嗯......你确定新的unsigned int5将整数归零吗?
显然是的:
[C++ 11:5.3.4/15]:创建类型为T的对象的new-expression初始化该对象,如下所示:如果省略new-initializer,则默认初始化对象(8.5); 如果没有执行初始化,则该对象具有不确定的值.否则,根据8.5的初始化规则解释new-initializer以进行直接初始化.
#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";
}
Run Code Online (Sandbox Code Playgroud)
结果:
> 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
>
Run Code Online (Sandbox Code Playgroud)
CB *_*ley 19
operator new
不保证将内存初始化为任何内容,并且在没有new-initializer的情况下分配a 的new-expression会使对象具有不确定的值.unsigned int
读取未初始化对象的值会导致未定义的行为.未定义的行为包括评估零值而没有不良影响但可能导致任何事情发生,因此您应该避免导致它.
在C++ 11中,使用的语言是分配的对象是默认初始化的,对于非类类型意味着不执行初始化.这与C++ 03 中default-initialized的含义不同.
对于某些编译器,new 的调试版本会初始化数据,但肯定没有什么可以依赖的。
\n\n也有可能内存在上次使用时只有 0。不要假设在删除和新建之间内存没有发生任何变化。可能在后台做了一些您从未注意到的事情。另外,相同的指针值可能不是相同的物理内存。内存页被移动、调出和调入。指针可能会映射到与之前完全不同的位置。
\n\n底线:如果您没有专门初始化内存位置,那么您就无法假设其内容。在您使用内存之前,内存管理器甚至可能不会分配特定的物理内存位置。
\n\n现代内存管理非常复杂,但作为 C++ 程序员,您并不真正关心(主要是 \xe2\x80\xa1)。遵守规则,你就不会惹上麻烦。
\n\n\xe2\x80\xa1 您可能会关心是否正在优化以减少页面错误。
\n