您的位置:首页 > 编程语言 > C语言/C++

C++指针之对未声明的地址进行访问

2011-03-22 12:10 471 查看
例1、

下列代码的运行结果是什么?

int *ptr;

ptr=(int *)0x8000;

*ptr=3;

解答:指针问题,首先将指针ptr指向一个指定的地址,即对一个未作声明的地址直接进行访问,所以访问出错。这块地址可能已经被用,或者被其他程序占用等,因此会导致错误。

例2、

下面这个程序在哪一行会崩溃?

struct S

{

int i;

int *p;

};

int main()

{

S s;

int *p=&s.i;

p[0]=4;

p[1]=3;

s.p=p;

s.p[1]=1;

s.p[0]=2;

return 0;

]

解析:

首先&s.i的地址赋给p,即p指向了i的地址,所以p[0]即为i,p[1]即为S中p指向的地址,即p[1]为*(p+1),p又为

i的地址,所以i的地址加一个int就是p的地址,即&p,再解引用*(&p)即为p此时指向的地址。

所以p的值为0x00000003,

然后s.p=p;

因为p还是存放着i的地址,此时赋值,即s.p=&s.i;即s中的p指向了s中的i的地址。

s.p[1]=1;

等价于*(&s.i+1)即i的地址加上一个int,即为p的地址&p,然后解引用即为p指向的地址,所以这句意思即为,为s中的p指向的地址赋值为1,所以s中p的值为0x00000001,此时s中的p就不再指向s中的i的地址了。

最后:s.p[0]=2;

即为*(s.p),即为s中的*p赋值,意思就是在内存0x00000001的上面赋值为2,这样对于一个未作声明的地址直接进行访问,所以出错,即是在s.p[0]=2;这句中崩溃的。

如果将最后两句调换则最终是正确的,即

s.p[0]=2;

s.p[1]=1;

这样是意思是一开始s中的p还是指向s中的i的地址的,s.p[0]=2;这句的意思就是为s中的i赋值为2,因为此时p还是指向i的地址的。

s.p[1]=1;

这句即为*(&s.i+1)即为p指向的地址,将p指向的地址赋值为1,即p指向的地址为0x00000001;所以最后就不会出错。

总结:

这两个例子都是为一个指定的地址赋值,在一个不确定的地址上面进行直接访问,导致出错。如果在一个确定可以访问的地址上进行赋值也是正确的,比如:

int *p = (int*)0x0018ff5c;
*p = 3;
std::cout<<*p<<std::endl;

在我机器上输出了3,说明这块内存是可以访问的,但是这块内存地址是不一定的,有的电脑上就有可能被占用。不过还有一种方式:

int i;
int m=(int)&i;
int *ptr;
ptr=(int *)m;
*ptr=3;

这样就是为一个指定的内存地址赋值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: