未初始化指针的奇怪行为 [英] Strange behavior with uninitialized pointers

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

问题描述

我正在用未初始化的指针观察这种奇怪的行为.

I am observing this strange behavior with uninitialized pointers.

从以下示例中可以看到,有时它以交替的方式打印NULL值,而其他人则打印有效地址.

As you can see from the following examples, sometimes it prints a NULL value while others it prints a valid address, in an alternating fashion.

为什么会这样?

代码:

int *i;
printf("%p\n", i);

输出:
(无)


Output:
(nil)


代码:

int *i;
printf("%p\n", i);

int *j;
printf("%p\n", j);

输出:
0x7fff2d0c1b50
(无)


Output:
0x7fff2d0c1b50
(nil)


代码:

int *i;
printf("%p\n", i);

int *j;
printf("%p\n", j);

int *k;
printf("%p\n", k);

输出:
(无)
0x7fffda5284b0
(无)


Output:
(nil)
0x7fffda5284b0
(nil)


代码:

int *i;
printf("%p\n", i);

int *j;
printf("%p\n", j);

int *k;
printf("%p\n", k);

int *l;
printf("%p\n", l);

输出:
0x400510
(无)
0x7fff6d7089c0
(无)


Output:
0x400510
(nil)
0x7fff6d7089c0
(nil)


代码:

int *i;
printf("%p\n", i);

int *j;
printf("%p\n", j);

int *k;
printf("%p\n", k);

int *l;
printf("%p\n", l);

int *m;
printf("%p\n", m);

输出:
0x357521cbc0
0x400520
(无)
0x7fff715849e0
(无)


Output:
0x357521cbc0
0x400520
(nil)
0x7fff715849e0
(nil)


系统:x86_64 x86_64 x86_64 GNU/Linux(x86_64-redhat-linux)
Compiler :gcc版本4.1.2 20080704(Red Hat 4.1.2-52)

System: x86_64 x86_64 x86_64 GNU/Linux (x86_64-redhat-linux)
Compiler: gcc version 4.1.2 20080704 (Red Hat 4.1.2-52)

推荐答案

通常,根本不使用未初始化的变量.如果您想了解更多,请继续阅读.

In general, just don't use uninitialized variables at all. If you want to know more, read on.

您的所有示例都是直接的未定义行为(UB),这是由于以下标准原因造成的:

All your examples are straight Undefined Behavior (UB), due to this standard passage:

6.3.2.1左值,数组和函数指示符

[...]
2 [...]如果左值指定了可以用register存储类声明的自动存储持续时间的对象(从未获取其地址),并且该对象未初始化(未使用初始化器声明且未分配) (已在使用前执行过),则该行为是不确定的.

6.3.2.1 Lvalues, arrays, and function designators

[...]
2 [...] If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

现在,让我们在地址省略的那一行中假装.

Now, let's pretend in some omitted line the address was taken.

&i; // Like this

6.2.4对象的存储期限

5一个对象,其声明的标识符没有链接,也没有存储类 说明符static具有自动存储期限,某些复合文字也具有自动存储期限. [...]
6 [...]对象的初始值不确定.

6.2.4 Storage durations of objects

5 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals. [...]
6 [...] The initial value of the object is indeterminate.

替代报价:

6.7.9初始化

[...]
10如果未自动初始化具有自动存储期限的对象,则其值为 不确定.

6.7.9 Initialization

[...]
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

3.19.2

1个不确定值
未指定值或陷阱表示形式

3.19.2

1 indeterminate value
either an unspecified value or a trap representation

1个未指定值
本国际标准未规定的相关类型的有效值 在任何情况下选择值的要求
2注意未指定的值不能是陷阱表示.

1 unspecified value
valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance
2 NOTE An unspecified value cannot be a trap representation.

1个陷阱表示形式
对象表示形式,不必表示对象类型的值

1 trap representation
an object representation that need not represent a value of the object type

6.2.6.1常规

5某些对象表示形式不必表示对象类型的值.如果存放 对象的值具有这种表示形式,并由执行以下操作的左值表达式读取 没有字符类型,则行为未定义.如果产生这样的表示 通过左值表达式修改对象的全部或任何部分的副作用 没有字符类型,则行为未定义.50)这种表示称为 陷阱表示.

6.2.6.1 General

5 Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.50) Such a representation is called a trap representation.

因此,如果您的实现支持所读取类型的陷阱表示(您不支持int*),则您具有 UB .

Thus, if your implementation supports trap-representations for the type you read (Yours don't for int*), you have UB.

因为您不这样做,所以使用未指定的值,这意味着每次读取都会返回一些任意值,而不必相同.

Because you don't, unspecified value applies, which means every read returns some arbitrary value, and not neccessarily the same.

所有报价均来自草案n1570,C99 +修订本,也称为C11.

All quotes are from draft n1570, C99+Ammendments aka C11.

这篇关于未初始化指针的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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