返回信息流下列代码给出输出结果:
#include"stdafx.h"
#include <iostream>
#include "stdlib.h"
using namespace std;
int main(void)
{
const int a = 10;
int * p = (int *)(&a);
*p = 20;
cout << "a = " << a << ", *p = " << *p << endl;
cout << &a << endl << p << endl; //本人测试时添加的
system("pause");
return 0;
}
运行结果如下:
这是一条镜像帖。来源:北邮人论坛 / cpp / #86336同步于 2015/4/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[问题]阿里笔试题:const int a = 10;int * p = (int *)(&a);*p
xut
2015/4/3镜像同步25 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
结果:什么都可能发生,从什么都不发生到机器冒烟都可能发生。
原因:p实际指向的存储空间是const int型的,往有const标注的存储空间里赋值是undefined behaviour。
【 在 nuanyangyang 的大作中提到: 】
: 结果:从什么都不发生到机器冒烟都可能发生。
: 原因:p实际指向的存储空间是const int型的,往这样的存储空间里赋值是undefined behaviour。
可是在vc2013中编译通过,运行正常。而且是多次运行。
运行结果a=10,a的值没被修改,可是指针P指向的确是a的地址,而对*P赋值20后,a的值居然没变。、
而且*P的值为20.那么P指向的内存在哪里?
从运行结果来看:*P和a的地址是一样的,那么为什么从同一地址中取出的值却不一样?
此题选项为:
A、编译时出错
B、编译正常,运行时出错
C、a=10,*P=10
D、a=10,*P=20
E、a=20,*P=10
F、a=20,*P=20
【 在 xut 的大作中提到: 】
:
: 可是在vc2013中编译通过,运行正常。而且是多次运行。
: 此题选项为:
: ...................
几个选项都不对。
所谓的“undefined behaviour”意思是语言的实现(包括编译器、运行库什么的)做任何事都可以。所以,vc2013能编译通过,而且给出某种“正常”的结果,都是允许的,因为编译器允许做任何事。
之所以会这样,是因为检查错误是有代价的,有时候,为了给出确定的行为,甚至是让程序运行时出错,都会让正确的程序的运行的效率大打折扣。比如,“取a的指针”不是错误,因为就算取了指针,以后也可能只是读而不写;“向*p里赋值”也不是错误,因为指针可以指向只读空间也可以指向读写空间,所以不便于编译时检查。所以,C语言的标准里干脆将其规定为“未定义行为”。它隐含的意思是:既然编译器、运行库做什么事都可以,那么程序员就必须尽一切努力来避免这样的事发生。所以,程序员如果写这样的程序,就是程序员的过失。
希望阿里的生产环境的应用里没有这样的代码。如果他们依赖于某种“特定的未定义行为”,你就该换个老板了。
【 在 xut 的大作中提到: 】
:
: 可是在vc2013中编译通过,运行正常。而且是多次运行。
: 运行结果a=10,a的值没被修改,可是指针P指向的确是a的地址,而对*P赋值20后,a的值居然没变。、
: ...................
对于你说的这一种特别的行为,可以有一种解释:编译器确实给a分配了可读写的空间,但优化器看到const,早就把所有的a的表达式的值翻译为常数10了。所以,对*p赋值,从*p读取,都是读的那个内存空间的值,所以看到的是20。
当然,不能依赖这种解释。别的编译器可以给a分配只读空间,这样,如果试图往里写,进程就会被操作系统干掉。
【 在 nuanyangyang 的大作中提到: 】
:
: 对于你说的这一种特别的行为,可以有一种解释:编译器确实给a分配了可读写的空间,但优化器看到const,早就把所有的a的表达式的值翻译为常数10了。所以,对*p赋值,从*p读取,都是读的那个内存空间的值,所以看到的是20。
: 当然,不能依赖这种解释。别的编译器可以给a分配只读空间,这样,如果试图往里写,进程就会被操作系统干掉。
在VC2013中,单步跟踪调试发现,a的地址和p中的值是一样的。给*P赋值20后,a和*P在内存中的值确实都变成20。只是在输出时a才等于10.被表象蒙蔽了。
非常感谢大神的细心解释。
【 在 FromMars 的大作中提到: 】
: 楼主吧 const int a = 10;
: 定义在全局部分试试?
定义在全局后,编译通过。运行出错。
unhandled exception at 0x01395EB8 in test.exe: 0xC0000005: Access violation writing location 0x0139C978.
【 在 xut 的大作中提到: 】
:
: 定义在全局后,编译通过。运行出错。
: unhandled exception at 0x01395EB8 in test.exe: 0xC0000005: Access violation writing location 0x0139C978.
果然被干掉了……
要不再试试变成
const int * p
【 在 xut 的大作中提到: 】
:
: 定义在全局后,编译通过。运行出错。
: unhandled exception at 0x01395EB8 in test.exe: 0xC0000005: Access violation writing location 0x0139C978.