短短几行代码,欢迎大家进来叙旧聊天拿分!

yiruirui0507 2010-09-07 11:58:19
struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3;
p[1]=3;
s.p=p;
// s.p[1]=(int)&p;
s.p[1]=1;
s.p[0]=2;
}

编译没出错,运行出错。题目有点诡异,大家给分析分析。先谢谢!看看哪里出了漏洞?
...全文
555 63 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
63 条回复
切换为时间正序
请发表友善的回复…
发表回复
yashuwa0622 2010-09-08
  • 打赏
  • 举报
回复
void main()
{
S s;
int *p=&s.i;
p[0]=3; //s.i=3;
p[1]=3; //此句被下面的一句屏蔽掉了,无用
s.p=p; //s.p=&s;
// s.p[1]=(int)&p;
s.p[1]=1; //s.p=1;
s.p[0]=2; // 此句相当于 *(int*)(1)=2,肯定是有问题的
}
kouji1990 2010-09-08
  • 打赏
  • 举报
回复
我也想知道为什么
上善若水邻 2010-09-08
  • 打赏
  • 举报
回复
昨天夜里没认真研究,所以错了现在再看我们发现问题出在p[1] = 0;这里

#include<iostream>
#include<string>
using namespace std;
struct S{
int i;
int *p;
};
int main(){
S s;
int *p = &s.i;
p[0] = 3;
p[1] = 0;//这时p[1]的地址是:00000000

cout<<"p的地址:"<<&p[0]<<"\t s.i的地址:"<<&s.i<<endl;
cout<<"p[1]的地址:"<<p[1]<<"\t s.i的地址:"<<&s.p<<endl;

cout<<"p[0]的值:"<<p[0]<<"\t s.i的值:"<<s.i<<endl;
cout<<"p[1]的值:"<<p[1]<<"\t s.p的值:"<<s.p<<"\t s.p的地址:"<<&s.p<<endl;
s.p = p;//这里的s.p保存的是p的地址,s.p本身的地址没变
cout<<"s.p的值:"<<s.p<<"\t s.p的地址:"<<&s.p<<endl;
s.p[0] = 1;
cout<<"s.p[0]的值:"<<s.p[0]<<"\t s.p[0]的地址:"<<&s.p[0]<<endl;
cout<<"s.p[1]的值:"<<s.p[1]<<"\t s.p[1]的地址:"<<&s.p[1]<<endl;
s.p[1] = 0;//问题出在这里了这时s.p[1]的地址改变为了00000004,而s.p的保存的值为0000000
cout<<"s.p[1]的地址:"<<&s.p[1]<<"\t s.p的值为:"<<s.p<<endl;
//cout<<"s.p[1]的值:"<<s.p[1]<<endl;如果加上这句就出错,因为s.p[1]的地址被改变为了00000004
//我们可能觉得s.p[1]指向的应该是s.p值,其实不是因为s.p的值没有改变
return 0;
}

到现在我还没有理解s.p[1]到底指向的是谁???
NoneSec 2010-09-08
  • 打赏
  • 举报
回复
额,看来我这功力太浅了,得继续学习啊……
dingshaofengbinbin 2010-09-08
  • 打赏
  • 举报
回复
嗯,不错!!!顶一下!!!
欣客 2010-09-08
  • 打赏
  • 举报
回复

#include "stdafx.h"

struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3;
p[1]=3;
s.p=p;
// s.p[1]=(int)&p;
// s.p[1]=1;
s.p[0]=2;
s.p[1]=1;
s.p[0] = 3;
}
这样就明白了, 因为s.p[1] = 1.把s.p 的地址改变了,s.p[0] = 2,是在s.p的地址上写,c++是不允许在没有分配空间的地址上读写的。所以报错。
你可以继续修改s.p[0]的值,你会发现这时候是写入不了的。
昵称很不好取 2010-09-08
  • 打赏
  • 举报
回复
好像程序员面试宝典上有这道题
weili_1 2010-09-08
  • 打赏
  • 举报
回复
......这么几句话,看着都要崩溃
yiruirui0507 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 pengzhixi 的回复:]
s.p[1]=1;//你这里将s.p里面的地址改为1
s.p[0]=2;//然后对地址为1的内存进行写,这肯定是不允许的。
[/Quote]

那交换一下为什么就不出错了呢?
yiruirui0507 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wizardoz 的回复:]
C/C++ code

struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3;
p[1]=3;
s.p=p;
// s.p[1]=(int)&p;
s.p[1]=1; // <== 这里还不越界吗?
s.p[0]=2;
}
[/Quote]

没越界的。
pengzhixi 2010-09-08
  • 打赏
  • 举报
回复
s.p[1]=1;//你这里将s.p里面的地址改为1
s.p[0]=2;//然后对地址为1的内存进行写,这肯定是不允许的。
WizardOz 2010-09-08
  • 打赏
  • 举报
回复

struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3;
p[1]=3;
s.p=p;
// s.p[1]=(int)&p;
s.p[1]=1; // <== 这里还不越界吗?
s.p[0]=2;
}

yiruirui0507 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ww884203 的回复:]
p[1]应该是s.p,也就是一个指针,你把指针赋了一个数字值,所以不对
[/Quote]

编译没错,运行出错,你的分析不对啊,再考虑考虑吧!
八哥 2010-09-08
  • 打赏
  • 举报
回复
struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3; //s.i=3
p[1]=3; //s.p=3 3不是一个有效地址,,导至s.p[1]出错
s.p=p;
// s.p[1]=(int)&p;
s.p[1]=1;
s.p[0]=2;
}
ww884203 2010-09-08
  • 打赏
  • 举报
回复
p[1]应该是s.p,也就是一个指针,你把指针赋了一个数字值,所以不对
yiruirui0507 2010-09-08
  • 打赏
  • 举报
回复
去掉s.p[1]=1; 改成
// s.p[1]=(int)p;就行啊


另外 s.p[1]=1;
s.p[0]=2;
交换一下就不会错

问题很诡异,自己跟踪了半天最后还是失踪了。
canshui 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 zecard_fu 的回复:]
引用 31 楼 canshui 的回复:

在上面的代码里面,最主要的是s.p的地址变成了1,这时候对s.p进行任何操作都是越界的
这里什么意思,s.p[1]=1,s.p的地址不是1啊,你这里说的不对吧?

楼主,这里确实改成1了

s.p 的地址没变! s.p 的值变了! s.p本身是个指针! s.p[1]也是*(s.p+1) s.p[0]也是*(s.p) 这里s.p是1 也就是 ……
[/Quote]

醍醐灌顶,受教了!……
yiruirui0507 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 44 楼 zecard_fu 的回复:]
引用 43 楼 yiruirui0507 的回复:

引用 42 楼 hawk198 的回复:
引用 40 楼 yiruirui0507 的回复:
难道因为0x1是系统的内存地址,我们无权修改吗?还是什么??

0x1是head代码,不属于我等能使用的


请问何为head代码,能给点资料或者解释吗?

看 赵烔 内核完全剖析! 第6章 引导启动程序!
[/Quote]

3ks!
macrojj 2010-09-08
  • 打赏
  • 举报
回复
s.p指向了自己。

然后 s.p不指向自己了。 指向个别的地方。
然后 尝试写。
大奶兔白糖 2010-09-08
  • 打赏
  • 举报
回复
struct S{
int i;
int *p;
};

void main(){
S s;
int *p=&s.i;
p[0]=3;
p[1]=3;
s.p=p;-->此时s.p指向了s.i的地址
// s.p[1]=(int)&p;
s.p[1]=1; -->导致s.p所指向的地址变为了0x00000001
s.p[0]=2;-->对地址0x00000001地址进行写操作,挂了……
}
加载更多回复(43)
中国功夫背景的《职业修炼》幻灯片模板下载; PPT内容简介: 心态、沟通、执行、时间。 心态: 子曰,人之生也直,罔之生也幸而免; 挑战自我,自我扬弃,与时俱进; 子曰:“参乎!吾道一以贯之。”曾子曰:“唯。”子出,门 人问曰:“何谓也?”曾子曰:“夫子之道,忠恕而已矣。” ——《论语·里仁》 沟通 一、倾听领导的要求        1.学会专注地倾听 2.领导要我们做什么 3.给予领导积极的反馈 4.虚心地接受批评 二、向领导请教问题        1.向你的领导学习 2.技巧性地提出问题 3.培养解决问题的能力 三、向领导汇报工作        1.分阶段汇报工作进度 2.活用各种汇报方式 3.掌握汇报工作的技巧 4.汇报我们的失误 四、获取领导的认可和支持        1.领导并没有那么顽固 2.技巧性地提出请求 3.向领导递交方案 五、化解与领导的分歧和矛盾        1.与各种类型的领导和谐相处 2.差异并不可怕 3.把分歧变成黏合剂 4.领导其实很容易被说服 六、巧妙地赞美领导        1.赞美领导升迁术 2.赞美绝不仅是“拍马屁” 3.和领导成为朋友 一、有效布置工作任务        1.准确地下达指令     2.充分授予下属工作自主权    3.做一个把握过程的主宰者 二、倾听下属的心声        1.打造畅通的沟通渠道 2.倾听下属心声也有技巧 3.妥善处理下属的意见 4.在会议中听取下属的意见 三、给予下属贴心的指导        1.把我们的经验倾囊传授给下属  2.真诚地关怀下属 3.培养下属。推动他的成长 四、激励下属积极工作        1.用赞美“讨好”下属  2.用激励提高团队士气  3.提升下属的责任心和使命感 五、让下属心悦诚服       1.说服下属有诀窍  2.拒绝下属的不合理要求  3.让下属将你视为榜样 4.权威效应让领导者“无为而治” 六、用批评促进下属成长       1.领导者不能做“老好人”  2.批评下属的艺术  3.建立惩罚规则的威慑性 七、化解矛盾和分歧       1.洞悉矛盾的本质   2.在沟通中化解矛盾的技巧   3.解决具体矛盾有高招 执行 本词条介绍的是一诺千金(汉语词典),更多含义,请参阅一诺千金(多义词)。 释 义:诺:承诺。许下的一个诺言有千金的价值。比喻说话算数,极有信用。 出 处:西汉·司马迁《史记·季布栾布列传》:“得黄金百,不如得季布诺。” 唐代·李白《叙旧赠江阳宰陆调》诗:“一诺许他人,千金双错刀。”错刀:古钱名。 如果没有结果,那么所有的理由都没有价值,因为执行的目的要的就是结果!当事情都做完了,你有一千、一万个理由都不重要,重要的是这个事情的结果是什么!   时间 1、事项清单的来源 每天上班第一件事,罗列“待完成”事项清单。 2、临时插单或预约的处理和提醒 随时记录,避免事项的遗漏 3、时间安排 将已经排序的事项,进行时间分配(即Deadline) 4、效果检视 当天工作按照效能四象限归类; 5、清单整理 每天晚上/每周结束时整理 关键词:黑色,黑白幻灯片背景,个性,功夫,中国功夫PowerPoint背景图片,中国风PPT模板,职场及工作方法幻灯片培训课件,.PPTX格式;

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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