运算符new将内存初始化为零

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)

  • @icepack:`operator new` 是一个用户(开发者)定义的函数,它可以为所欲为。该标准没有限制此功能的作用。就像 `operator==` 可以做任何用户定义的事情(它甚至不需要返回 bool 更不用说测试相等性(尽管如果它不这样做,它是不好的形式))。 (2认同)

CB *_*ley 19

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

读取未初始化对象的值会导致未定义的行为.未定义的行为包括评估零值而没有不良影响但可能导致任何事情发生,因此您应该避免导致它.

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


Mic*_*l J 5

对于某些编译器,new 的调试版本会初始化数据,但肯定没有什么可以依赖的。

\n\n

也有可能内存在上次使用时只有 0。不要假设在删除和新建之间内存没有发生任何变化。可能在后台做了一些您从未注意到的事情。另外,相同的指针值可能不是相同的物理内存。内存页被移动、调出和调入。指针可能会映射到与之前完全不同的位置。

\n\n

底线:如果您没有专门初始化内存位置,那么您就无法假设其内容。在您使用内存之前,内存管理器甚至可能不会分配特定的物理内存位置。

\n\n

现代内存管理非常复杂,但作为 C++ 程序员,您并不真正关心(主要是 \xe2\x80\xa1)。遵守规则,你就不会惹上麻烦。

\n\n

\xe2\x80\xa1 您可能会关心是否正在优化以减少页面错误。

\n