自动和动态变量规则在零初始化中的差异
这样的代码,
#include <iostream>
class obj
{
public:
int v;
};
int main(int argc, char *argv[])
{
obj o1;
std::cout << o1.v << std::endl; // print 32766, indeterminate values
obj *o2 = new obj();
std::cout << o2->v << std::endl; // print 0,but why?
int v1;
std::cout << v1 << std::endl; // print 22024, indeterminate values
int *v2 = new int;
std::cout << *v2 << std::endl; // print 0,but why?
return 0;
}
我知道全局或静态变量将被初始化。
自动做不确定的值。
但是堆对象使用新关键字,有任何引用来解释它吗?
code like this,
#include <iostream>
class obj
{
public:
int v;
};
int main(int argc, char *argv[])
{
obj o1;
std::cout << o1.v << std::endl; // print 32766, indeterminate values
obj *o2 = new obj();
std::cout << o2->v << std::endl; // print 0,but why?
int v1;
std::cout << v1 << std::endl; // print 22024, indeterminate values
int *v2 = new int;
std::cout << *v2 << std::endl; // print 0,but why?
return 0;
}
I know the global or static variables will be initialize zero.
and automatic does the indeterminate values.
but the heap object use new keyword, has any reference to explain it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
obj *o2 = new obj();
是值初始化这意味着该对象的初始化为零,因此数据成员v
将被初始化为0
。可以从值初始化:
另一方面,
以上会导致不确定的行为,因为您正在提取
v2
,并且分配的int
对象是非初学的,因此不确定价值。不确定的行为意味着任何事情都可能发生。但是,永远不要依靠(或基于结论),该程序的输出具有UB。该程序可能只是崩溃。
从默认初始化:
obj *o2 = new obj();
is value initialization meaning the object will be zero initialized and hence the data memberv
will be initialized to0
.This can be seen from value initialization:
On the other hand,
the above leads to undefined behavior because you're dereferencing
v2
and the allocatedint
object has is uninitialized and so has indeterminate value.Undefined behavior means anything can happen. But never rely(or make conclusions based) on the output of a program that has UB. The program may just crash.
This can be seen from default initialization:
从C ++ 17标准(11.6个初始化器)
对于基本类型,它意味着零限制。
因此,在此声明中,
动态分配的对象的数据成员
v
被零定位。至于此代码段
,则未初始化指针
v2
指向的对象,下一个输出语句可以输出在分配新对象的内存范围内存储的任何值。From the C++ 17 Standard (11.6 Initializers)
For fundamental types as int it means zero-initialization.
So in this declaration
the data member
v
of the of the dynamically allocated object is zero-initialized.As for this code snippet
then the object pointed to by the pointer
v2
is not initialized and the next output statement can output any value that was stored in the memory extent where the new object is allocated.初始化规则是一团糟。因此,让我们只是踩它们并强制问题:
现在,
v
始终将被初始化。如果您添加一个不初始化v
的构造函数,则可以有效,因为编译器会自动添加成员初始化。至于为什么您的代码表现得如此之多:
o1
是在堆栈(或实际上是寄存器)上创建的,默认初始化。对于int
,这意味着没有初始化。堆栈上(或寄存器中)上的任何随机数据都是您得到的。从C ++ 17标准(11.6个初始化器):
值初始化
int
将其设置为0。默认初始化,您将获得随机数据。
默认初始化,您将获得随机数据。除非应用程序重复使用,否则新鲜分配的内存恰好是0。
Initialization rules are a mess to remember. So lets just side step them and force the issue:
There, now
v
is always going to be initialized. That even works if you add a Constructor that doesn't initializev
as then the member initialization is added automatically by the compiler.As for why your code behaved as it did:
o1
is created on the stack (or actually a register) and default initialized. Which for theint
means no initialization. Whatever random data is on the stack (or in the register) is what you get.From the C++ 17 Standard (11.6 Initializers):
Value initialization of
int
sets it to 0.Default initialization and you get random data.
Default initialization and you get random data. Freshly allocated memory just happens to be 0 unless it's reused by the application.