VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 7715|回复: 28

一个令人疯掉的C指针问题,不是搞编译器的绝对想不到

[复制链接]
 楼主| 发表于 2010-5-26 11:36:37 | 显示全部楼层 |阅读模式
本帖最后由 VBProFan 于 2010-5-26 14:16 编辑

问题来源于 http://www.vcgood.com/bbs/forum_posts.asp?TID=648
我对它做了扩展的思考。

VC6 Debug 版本:

  1. #include <stdio.h>
  2. void main()
  3. {
  4. int c[1] = {7};
  5. int a[5] = {1,2,3,4,5};
  6. int b[1] = {6};
  7. int *ptr = (int*)(&a+1);
  8. printf("%d\n",*ptr);
  9. }
复制代码
输出结果是什么?如果YY的功力不够,可以看2楼的图得到一点提示,但我估计你即使看了它还是猜不出结果是什么。
 楼主| 发表于 2010-5-26 11:39:15 | 显示全部楼层
本帖最后由 VBProFan 于 2010-5-26 11:47 编辑

如果是 Release 版本,又是另一个差得很远、很雷人的结果了……
下面是 Debug 版本的调试截图:
Debug.JPG
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 11:58:04 | 显示全部楼层
问题1:为什么 Debug 版本的内存分配是 6 在前,7 在后?
问题2:&a + 1 转成指针类型后为什么指向整个数组的末尾而不是指向 &a 的下一个字节?
问题3:Release 版本中的内存分配又如何?为什么得到那个结果?
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2010-5-26 11:58:05 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 13:41:02 | 显示全部楼层
本帖最后由 VBProFan 于 2010-5-26 13:47 编辑
我个突然 vc 小了 libcb.lib 文件...楼上给我传一下好吗?...谢谢谢谢
lekj 发表于 2010-5-26 11:58

我这里只有 LIBCD.LIB

5:        int c[1] = {7};
0040D858   mov         dword ptr [ebp-4],7
6:        int a[5] = {1,2,3,4,5};
0040D85F   mov         dword ptr [ebp-18h],1
0040D866   mov         dword ptr [ebp-14h],2
0040D86D   mov         dword ptr [ebp-10h],3
0040D874   mov         dword ptr [ebp-0Ch],4
0040D87B   mov         dword ptr [ebp-8],5
7:        int b[1] = {6};
0040D882   mov         dword ptr [ebp-1Ch],6
8:        int *ptr = (int*)(&a+1);
0040D889   lea         eax,[ebp-4] ;//<---为什么要编译为这个?
0040D88C   mov         dword ptr [ebp-20h],eax
9:        printf("%x\n",*ptr);
0040D88F   mov         ecx,dword ptr [ebp-20h]
0040D892   mov         edx,dword ptr [ecx]
0040D894   push        edx
0040D895   push        offset string "ABCDE" (0042201c)
0040D89A   call        printf (00401130)
0040D89F   add         esp,8

LIBCD.rar

412.89 KB, 下载次数: 664

评分

参与人数 1威望 +4 人气 +1 收起 理由
lekj + 4 + 1 thanks

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 13:59:30 | 显示全部楼层
本帖最后由 VBProFan 于 2010-5-26 14:12 编辑
问题1:为什么 Debug 版本的内存分配是 6 在前,7 在后?
问题2:&a + 1 转成指针类型后为什么指向整个数组的末尾而不是指向 &a 的下一个字节?
问题3:Release 版本中的内存分配又如何?为什么得到那个结果?
VBProFan 发表于 2010-5-26 11:58


我现在已经得到问题2的一半的答案了……

之所以说是一半,是因为还有一些问题想不通:

问题4:为什么 Watch Window 显示的 &a+1 的值和该值转换为指针时的意义不同?
问题5: int *ptr = (int*)(&a+1); 和 int ptr =  (int)(*(&a+1)); 这两种写法是等价的还是结果相同纯属偶然?

PS:只有 printf("%x\n",(int)(&a)+1); 的结果在我意料之中,其余的都很怪异。
回复 支持 反对

使用道具 举报

发表于 2010-5-26 15:20:00 | 显示全部楼层
&a的类型是int[5]*
也就是说对其+1的话
相当于数值运算+sizeof(int[5])
加了20就
其他的比较饶,还没想通

评分

参与人数 1威望 +12 收起 理由
VBProFan + 12 精品文章

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 17:11:54 | 显示全部楼层
&a的类型是int[5]*
也就是说对其+1的话
相当于数值运算+sizeof(int[5])
加了20就
其他的比较饶,还没想通
仙剑魔 发表于 2010-5-26 15:20


意思是 &a 是一种新的数据类型了? &a + 1 和 (int)(&a) + 1 中的 &a 不同?
&a 不是表示取a的地址吗?怎么又变为一种新的数据类型了?雷。。。
回复 支持 反对

使用道具 举报

发表于 2010-5-26 19:06:25 | 显示全部楼层
8# VBProFan

&x
x是什么类型
&x就是什么类型的指针
(int)(&x)转换以后就变成数值了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 19:23:26 | 显示全部楼层
8# VBProFan  

&x
x是什么类型
&x就是什么类型的指针
(int)(&x)转换以后就变成数值了
仙剑魔 发表于 2010-5-26 19:06


原来还能这样子,学习了
回复 支持 反对

使用道具 举报

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

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2023-3-22 05:11

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表