鱼C论坛

 找回密码
 立即注册
查看: 4320|回复: 12

关于指针型类成员的赋值问题

[复制链接]
发表于 2012-7-18 23:31:07 | 显示全部楼层 |阅读模式
2鱼币
本帖最后由 Mr.C 于 2012-7-18 23:33 编辑

为什么
  1. void main()
  2. {
  3. int* i;
  4. *i = 5;
  5. }
复制代码
可以。


  1. class A
  2. {
  3. public:
  4.        A()
  5.        {
  6.              // x=new int;
  7.             *x=5;
  8.        }
  9. private:
  10.       int* x;
  11. };
复制代码



不可以。而是要new一个空间才能赋值。 为什么会这样。
最好是能从汇编角度解答一下这个问题。

最佳答案

查看完整内容

i是局部变量,由于没有初始化,它的值是随机值。为了方便假设是2012 *i=5向内存单元2012写如一个整数5.如果运气好2012这个单元没存放什么重要的数据,就不会报错,如果运气不好,2012这个单元存放了什么重要的数据,就运行时报错。 如果试验100次,99次运气好,1次运气不好。那么这个bug就会由于很难重现而不被发现。 以上是根据C语言标准作的解释。至于汇编层面,由于不同的C/C++语言编译器实现不同,汇编代码也不同。
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2012-7-18 23:31:08 | 显示全部楼层
  1. void main()
  2. {
  3. int* i;
  4. *i = 5;
  5. }
复制代码
i是局部变量,由于没有初始化,它的值是随机值。为了方便假设是2012
*i=5向内存单元2012写如一个整数5.如果运气好2012这个单元没存放什么重要的数据,就不会报错,如果运气不好,2012这个单元存放了什么重要的数据,就运行时报错。

如果试验100次,99次运气好,1次运气不好。那么这个bug就会由于很难重现而不被发现。
以上是根据C语言标准作的解释。至于汇编层面,由于不同的C/C++语言编译器实现不同,汇编代码也不同。

点评

光老师一针见血。  发表于 2012-7-19 19:16
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-18 23:54:41 | 显示全部楼层
int *x是声明了x这个指针,但是没有为他分配空间
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 00:30:35 | 显示全部楼层
你定义类的时候 本来就是一个 抽象的 类型 在没定义对象的时候 就没为这个类的 私有成员分配空间啊 只有在定义对象 或者 用new 出一个动态空间来存放这些私有数据变量 才会为它开辟存储空间啊 不然不能赋值
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 00:30:57 | 显示全部楼层
自己是这样理解的 不对请勿喷
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 00:44:04 | 显示全部楼层
从汇编角度说就是  
对象地址+变量偏移赋值
所以你这个类成员指针偏移0
这个指针地址就是你定义的对象地址
  1. #include <iostream.h>
  2. class A
  3. {
  4. public:
  5.     A()
  6.     {
  7.         // x=new int;
  8.         *x=5;
  9.     }
  10. public:
  11.     int* x;
  12. };
  13. int main(int argc, char* argv[])
  14. {
  15.     int a = 10;
  16.     //x偏移
  17.     cout << hex << &((A*)NULL)->x << endl;
  18.     //a地址为12ff7c 所以x地址为12ff7c 所以输出a的值
  19.     cout <<  ((A*)0x12ff7c)->x << endl;
  20.         return 0;
  21. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 12:20:39 | 显示全部楼层
int * x ;
*x = 5;  
汇编代码 (VC++6.0 debug)
00401054 8B 45 EC             mov         eax,dword ptr [ebp-14h]
00401057 C7 00 05 00 00 00    mov         dword ptr [eax],5

这里你可以看到,是先把x即([ebp-14h])的值给了eax,然后  把5放到[eax]里面,因为这里x没有初始值,运行的话肯定会报错。

下面看你的
class  那样的话  定义一个你那样的类,然后在主函数里面调用的话汇编代码如下:
00401054 8D 4D EC             lea         ecx,[ebp-14h]
00401057 E8 B3 FF FF FF       call        @ILT+10(AA::A) (0040100f)

这里lea ecx,[ebp - 14h] 是寄存器传参,lea  指令说明传过去的时候 x的地址,然后看你的方法函数内部汇编:
0040147A 89 4D FC             mov         dword ptr [ebp-4],ecx
13:           *x = 5;
0040147D 8B 45 FC             mov         eax,dword ptr [ebp-4]
00401480 8B 08                mov         ecx,dword ptr [eax]
00401482 C7 01 05 00 00 00    mov         dword ptr [ecx],5
这里是不是很清晰?  因为前面说了参数放在ecx,所以ecx里面放的x的地址,若你会汇编,我觉得这些都能看懂吧。。。

还有我不晓得你问的问题到底是为了问什么,你的那两种写法编译都能通过,执行的时候都是会报内存读写错误,申请内存的话不会。。。。。原因就是 int *x  这里没有对x进行初始化,然后后面直接*x,因为x的值位系统随机值,debug版本下是0xcccccccc, 这个地址你没有访问权限,所以执行错误,若是你把x初始化为一个有效的地址,例如0x12ff7c    ,就不会有事。。。当然申请内存的话也肯定不会报错,申请内存跟你初始化是一个道理,其实,就是找了一个、你可以访问的地址。。。一个是自己可以安排,一个是系统帮你分配
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 12:22:44 | 显示全部楼层
LS 大神出来了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 12:24:46 | 显示全部楼层
对于[ebp - 14h] 这个东西,LZ不要纠结,因为我是在我自己的工程里面随便写了一个类试了一下,按正常的如果是个空工程的话 就是  [ebp - 4]   32位PC机这是标准的第一个局部变量的地址。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 12:44:43 | 显示全部楼层
  1. void main()
  2. {
  3. int* i;
  4. *i = 5;
  5. }
复制代码
这个不是可以 这个是不可以
能运行也不对
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 16:46:32 | 显示全部楼层

小弟还是没有理解,我们老师教的时候强调不能用一个常量去给指针赋值,为什么第一种楼主说可以???
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-19 17:36:12 | 显示全部楼层
肥猫控 发表于 2012-7-19 16:46
小弟还是没有理解,我们老师教的时候强调不能用一个常量去给指针赋值,为什么第一种楼主说可以???

int *x,这时候x是一个指针型的变量,它放的是一个int型内存空间的地址,且可以用*x所以这个地址。如果你自己用常数赋值给x的话(x=5),就会变成x这个指针指向地址为5的内存空间,之后如果你对它改变的话容易造成系统出问题,所以限制了。而   *x=5就相当于给x指向的内存空间赋值,由于是系统给你分配的,所以不会出现错误,所以可以。应该是这样理解的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-7-24 22:10:07 | 显示全部楼层
大神们 说的 太好 另外     学习了  。。。。。:'(:'(
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-14 05:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表