一道微软笔试题-不解?
struct S {
int i;
int * p;
};
void main()
{
S s; //1
int * p = &s.i; //2
p[0] = 4; //3
p[1] = 3; //4
s.p = p; //5
s.p[1] = 1; //6
s.p[0] = 2; //7
}
问:该程序运行到哪一步就出错?
我用VC单步调试,发现到第7步就出错,但其实第4步步是就非法操作了吗,为什么到第7步才出错了呢?
还有,我还发现一个怪问题,如果把以上该为:
#include <iostream.h>
struct S {
int i;
int * p;
};
void main()
{
S s; //1
int n = 10; //2
int * p = &n; //3
p[0] = 4; //4
p[1] = 3; //5
cout < < p[1] //6
< < endl; //7
}
该程序运行正常,输出3,但是如果把第一步的去掉,该程序就出错,为什么?
我用的编译器是VC6.0
[解决办法]
void main()
{
S s; //1
int * p = &s.i; //2
p[0] = 4; //3
p[1] = 3; //4 只是给指针赋了一个非法的值,不会出错
s.p = p; //5
s.p[1] = 1; //6 给指针赋了一个非法的值,不会出错
s.p[0] = 2; //7 对一个非法的指针解引用,出错
}
[解决办法]
s.p[1] = 1; //6
s.p[0] = 2; //7
第7行等于是 *(0x00000001) = 2;
当然就出错了,
[解决办法]
void main()
{
S s; //1
int * p = &s.i; //2
p[0] = 4; //3
p[1] = 3; //4
s.p = p; //5
s.p[1] = 1; //6 这时S里的p值为1(i是32位的,p也是32位的,所以正好放在一个int数组中,对s.p[1]的操作就是对p值的操作)
s.p[0] = 2; //7 s.p[0]这个地址值已经为负了
}
[解决办法]
s.p[1] = 1; //6
s.p[0] = 2; //7
上面说的都对,至于为什么会变成0x00000001,就是第六步给s.p[1]进行的赋值操作,将结构体内的指针值改变为指向0x00000001了