Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 运算符new将内存初始化为零_C++_Memory Management - Fatal编程技术网

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

C++ 运算符new将内存初始化为零,c++,memory-management,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 << "wsk

有这样的代码:

#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;
}

我读到
new
不会用零初始化内存。但在这里似乎是这样。它是如何工作的?

这不是新的
操作符,而是新的
操作符。事实上有很大的不同!区别在于
操作符new
是一个返回原始内存的函数;当您使用
new
操作符时,它会为您调用一个构造函数。构造函数设置
int
的值,而不是
运算符new

运算符new
不能保证将内存初始化为任何内容,并且分配
无符号int
的新表达式不使用新的初始值设定项,会给对象留下一个不确定的值

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


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

有两个版本:

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)
在回答下面的评论时

嗯。。。您确定
新的无符号整数[5]()
会将整数归零吗

显然是的:

[C++11:5.3.4/15]:创建类型为T的对象的新表达式按如下方式初始化该对象:如果省略新的初始化器,则该对象默认已初始化(8.5);如果未执行初始化,则对象的值不确定。否则,新的初始值设定项将根据8.5的初始化规则进行解释,以进行直接初始化


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

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

一句话:如果你没有特别初始化一个内存位置,那么你就不能假设它的内容是什么。在使用内存之前,内存管理器甚至可能不会分配特定的物理内存位置

现代内存管理非常复杂,但作为C++程序员,你并不真正关心(大部分是)。遵守规则,你就不会惹麻烦


——“如果您正在优化以减少页面错误,您可能会在意。

否则,您必须使用新的unsigned int()。读取未初始化的变量是UB,0当然是可能的。顺便说一句,实际上很多内存都是零。如果对一大块内存执行简单的malloc操作,在某些系统上通常都是零,或者在其他系统上大多是零。@NicholasWilson:对于大多数系统,只有当内存直接来自操作系统时(出于安全原因),这才是真的。当它来自分配器缓存的内存时,它很可能包含在空闲()d之前所做的任何事情。这也是为什么这些bug有时不会出现在测试用例/单元测试中,而只是在“真正的”程序运行一段时间后才会出现的原因。瓦尔格林来这里救援,是的。这是我的观点。如果你创建了一个新变量,看到它是零,你不能马上假设你的程序中有什么东西把它设置为零。由于大多数内存都已归零,所以它可能还未初始化。我认为我的评论实际上比下面的大多数答案更接近于回答这个问题,因为提问者想知道为什么未初始化的内存可能为零。尝试分配一个数组,将所有项设置为非零值,然后删除[]然后再次分配它-只有第一项将被归零-其他项保留它们的值-我认为这是内存分配器(在Linux下测试)的特殊性。我认为正确的术语是“new expression”,它调用相应的新操作符。那么重载的
new/new[]
操作符呢?
newunsigned int[5]()
是否仍然会对数组进行零初始化,即使它有一个专有的、完全无关的实现?@icepack:the
operator new
是一个用户(开发人员)定义的函数,它可以做任何它喜欢的事情。该标准没有对该函数的功能进行限制。就像
operator==
可以执行用户定义的任何操作(它甚至不需要返回bool,更不用说测试是否相等了(如果不返回,则格式不好))。谢谢。需要明确的是:我的专有分配器的实现与零初始化无关,如果使用
()
语法,缓冲区将被零初始化,而与所分配对象的类型及其构造函数没有任何关系?(我想C++11在这方面没有任何改变)嗯。。。您确定
newunsigned int[5]()
会将整数归零吗?@J3STER通过新调用传递指针称为placement new。请参见
8.3.4新增的
。为什么要修改。因为我们正在强制值初始化。请参见
11.6初始值设定项
。注意,我们正在传递一个指向新操作符的指针。
wsa
的值未更改,更改的是指向的地址。
wsa = new unsigned int[5];   // default initialized (ie nothing happens)
wsa = new unsigned int[5](); // zero    initialized (ie all elements set to 0)
#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
>