程序会在哪报错?

iceli 2012-10-29 11:41:23
#include<iostream>
using namespace std;
typedef struct{
int i;
int *p;
}S;
void main()
{
S s;
cout<<s.i<<" "<<s.p<<endl;
int *p=&s.i;
p[0]=4;
p[1]=3;
s.p=p;
s.p[1]=1;
s.p[0]=2;//Access Violation,为什么?
}
32-bit X86 PC上运行该程序会在哪出错?为什么?Linux系统会报告何种错误?
...全文
190 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wingzero520 2012-10-29
  • 打赏
  • 举报
回复
如果是在 32 位系统下,那么 int 占 4 个字节,int* 也占4个字节。
假设 s 结构体位于内存地址 0x500000 处。
那么 s.i 位于 0x500000,s.p 位于 0x500004 。

p[0]=4; // 相当于 s.i=4
p[1]=3; // 相当于 s.p=(int*)3,由于 p 是指针,你这句话强制让一个指针指向地址为 3 的内存,但由于没有访问操作,所以没事
s.p=p; // 由于 p 指向 s.i,那么这句话就相当于 s.p=&s.i,也就是 0x500000
s.p[1]=1; // s.p 是 int* ,[1] 即指针值 +4,那么 s.p[1] 取的是 0x500004 处的值,正好是 s.p 自己。也就是将 s.p 自己赋成了1。
s.p[0]=2; // 上一行已经把 s.p 改成了 1,地址为 1 内存区域一般不可访问,故 Access Violation
JiMoKuangXiangQu 2012-10-29
  • 打赏
  • 举报
回复
s.p = p;
使得s.p == &s.i
s.p[1] = 1;
使得s.p == 0x00000001
所以s.p[0]相当于访问地址0x00000001.

Linux是报Segment Fault错误吧.
Flammable_ice 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
如果是在 32 位系统下,那么 int 占 4 个字节,int* 也占4个字节。
假设 s 结构体位于内存地址 0x500000 处。
那么 s.i 位于 0x500000,s.p 位于 0x500004 。

p[0]=4; // 相当于 s.i=4
p[1]=3; // 相当于 s.p=(int*)3,由于 p 是指针,你这句话强制让一个指针指向地址为 3 的内存,但由于没有访问操作……
[/Quote]
看了半天才看懂,又详细,又清楚,楼主可以结贴了哦。
iceli 2012-10-29
  • 打赏
  • 举报
回复
牛人,解释得很详细,多谢!
[Quote=引用 2 楼 的回复:]
如果是在 32 位系统下,那么 int 占 4 个字节,int* 也占4个字节。
假设 s 结构体位于内存地址 0x500000 处。
那么 s.i 位于 0x500000,s.p 位于 0x500004 。

p[0]=4; // 相当于 s.i=4
p[1]=3; // 相当于 s.p=(int*)3,由于 p 是指针,你这句话强制让一个指针指向地址为 3 的内存,但由于没有访问操作……
[/Quote]
zhangxun2007 2012-10-29
  • 打赏
  • 举报
回复
考试题么,好强啊!
Mr_micro 2012-10-29
  • 打赏
  • 举报
回复
灰常详细
我爱吃火锅 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

如果是在 32 位系统下,那么 int 占 4 个字节,int* 也占4个字节。
假设 s 结构体位于内存地址 0x500000 处。
那么 s.i 位于 0x500000,s.p 位于 0x500004 。

p[0]=4; // 相当于 s.i=4
p[1]=3; // 相当于 s.p=(int*)3,由于 p 是指针,你这句话强制让一个指针指向地址为 3 的内存,但由于没有访问操……
[/Quote] 解释很详细~
请叫我杨二哥 2012-10-29
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
typedef struct{
int i;
int *p;
}S;
void main()
{
S s;
cout<<s.i<<" "<<s.p<<endl;
int *p=&s.i;//此时p指向的是s结构体中的i的地址
p[0]=4;//此时p[0]既是修改的是s.i的值
p[1]=3;//p[1]修改s.p的值
s.p=p;//此处 再让s.p指向p
s.p[1]=1;//s.p[1] 修改的是指向s.p的值
s.p[0]=2;//修改的是s.i的地址,但是s.i是已经被分配好的不能修改的地址,所以出现错误。即所谓的访问越界。不知道你以为对不
}
Eleven 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
如果是在 32 位系统下,那么 int 占 4 个字节,int* 也占4个字节。
假设 s 结构体位于内存地址 0x500000 处。
那么 s.i 位于 0x500000,s.p 位于 0x500004 。

p[0]=4; // 相当于 s.i=4
p[1]=3; // 相当于 s.p=(int*)3,由于 p 是指针,你这句话强制让一个指针指向地址为 3 的内存,但由于没有访问操作……
[/Quote]
解释的很清楚了~

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧