未初始化的数据行为是否明确指定? [英] Is uninitialized data behavior well specified?

查看:111
本文介绍了未初始化的数据行为是否明确指定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我使用的是g ++编译器(这听起来不错,应该很接近标准)。

Note: I am using the g++ compiler (which is I hear is pretty good and supposed to be pretty close to the standard).

我可以想到最简单的一类:

I have the simplest class I could think of:

class BaseClass  {
  public:
    int pub;
};

然后我有三个同样简单的程序来创建 BaseClass 对象并打印出其数据的[未初始化]值。

Then I have three equally simple programs to create BaseClass object(s) and print out the [uninitialized] value of their data.

BaseClass B1;
cout<<"B1.pub = "<<B1.pub<<endl;

这将输出:

B1.pub = 1629556548

我实际上认为它会初始化为零,因为它是一个POD或普通数据类型或类似的东西,但我猜不是?到目前为止这么好。

Which is fine. I actually thought it would get initialized to zero because it is a POD or Plain Old Datatype or something like that, but I guess not? So far so good.

BaseClass B1;
cout<<"B1.pub = "<<B1.pub<<endl;
BaseClass B2;
cout<<"B2.pub = "<<B2.pub<<endl;

这将输出:

B1.pub = 1629556548
B2.pub = 0

这肯定是奇怪的。我创建了两个相同的对象相同的确切方式。

This is definitely weird. I created two of the same objects the same exact way. One got initialized and the other did not.

BaseClass B1;
cout<<"B1.pub = "<<B1.pub<<endl;
BaseClass B2;
cout<<"B2.pub = "<<B2.pub<<endl;
BaseClass* pB3 = new BaseClass;
cout<<"B3.pub = "<<pB3->pub<<endl;

这将输出:

B1.pub = 0
B2.pub = 0
B3.pub = 0

这是最奇怪的。它们都被初始化为零。所有我做的是添加两行代码,它改变了以前的行为。

This is the most weird yet. They all get initialized to zero. All I did was add two lines of code and it changed the previous behavior.

我真的想了解默认的构造函数/析构函数的行为,因为我有一个非特定的行为,一个感觉,它将是非常重要的完全理解继承的东西。

I really want to understand the default constructor/destructor behavior because I have a feeling that it will be very important for completely understanding the inheritance stuff..

推荐答案


这只是一个未初始化的数据导致未指定的行为的情况

So is this just a case of 'uninitialized data leads to unspecified behavior'

是...

有时候如果你调用 malloc (或 new / code>),你会得到填充零的数据,因为它在内核的新页面。其他时候,它将充满垃圾。如果你把一些东西放在堆栈(即汽车存储),你几乎肯定会得到垃圾 - 但它可能很难调试,因为在系统,垃圾可能会有一定的可预测性。对于栈上的对象,你会发现在一个完全不同的源文件中改变代码可能会改变你在未初始化的数据结构中看到的值。

Sometimes if you call malloc (or new, which calls malloc) you will get data that is filled with zeroes because it is in a fresh page from the kernel. Other times it will be full of junk. If you put something on the stack (i.e., auto storage), you will almost certainly get garbage — but it can be hard to debug, because on your system that garbage might happen to be somewhat predictable. And with objects on the stack, you'll find that changing code in a completely different source file can change the values you see in an uninitialized data structure.

关于POD:无论POD是否是一个真正的鲱鱼。我只解释了它,因为提到的问题POD,和谈话脱轨。两个相关概念是存储持续时间和构造函数。 POD对象没有构造函数,但是没有构造函数的都不是POD。 (技术上,POD对象不具有<​​em>非平凡的构造函数,也不具有非平凡构造函数的成员。)

About POD: Whether or not something is POD is really a red herring here. I only explained it because the question mentioned POD, and the conversation derailed from there. The two relevant concepts are storage duration and constructors. POD objects don't have constructors, but not everything without a constructor is POD. (Technically, POD objects don't have non-trivial constructors nor members with non-trivial constructors.)

有三种。 静态是全局变量的自动 (这是一个简化,但不完全正确,但如果你需要一些正确的东西,你可以自己读出C ++标准。)

Storage duration: There are three kinds. Static duration is for globals, automatic is for local variables, and dynamic is for objects on the heap. (This is a simplification and not exactly correct, but you can read the C++ standard yourself if you need something exactly correct.)

任何静态存储持续时间被初始化为零。因此,如果你创建一个 BaseClass 的全局实例,那么它的 pub 成员将为零。因为你把它放在堆栈和堆上,这条规则不适用 - 你不做任何其他事情来初始化它,所以它是未初始化的。

Anything with static storage duration gets initialized to zero. So if you make a global instance of BaseClass, then its pub member will be zero (at first). Since you put it on the stack and the heap, this rule does not apply — and you don't do anything else to initialize it, so it is uninitialized. It happens to contain whatever junk was left in memory by the last piece of code to use it.

通常,堆或堆栈上的任何POD都将被初始化除非您自己初始化它,并且值将是未定义的,当您重新编译或再次运行程序时可能会更改。

As a rule, any POD on the heap or the stack will be uninitialized unless you initialize it yourself, and the value will be undefined, possible changing when you recompile or run the program again. As a rule, any global POD will get initialized to zero unless you initialize it to something else.

检测未初始化的值:尝试使用Valgrind的memcheck工具,它将帮助您找到使用未初始化值的位置 - 这些通常是错误。

Detecting uninitialized values: Try using Valgrind's memcheck tool, it will help you find where you use uninitialized values — these are usually errors.

这篇关于未初始化的数据行为是否明确指定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆