当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 9 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : [问题]数组下标越界发现的问题
帖子发表于 : 2007-09-30 11:28 

注册: 2007-09-14 19:51
帖子: 972
送出感谢: 0 次
接收感谢: 0 次
编译下列代码并运行会输出不固定的数字
代码:
#include<iostream>
int main()
{
    int b[7];
    std::cout<<b[7]<<std::endl;
    return 0;
}



但是编译下列代码会并运行会输出:7
代码:
#include<iostream>
int main()
{
    const int a=7;
    int b[a];
    std::cout<<b[a]<<std::endl;
    return 0;
}


把上面的代码中的 a改成什么数字,运行结果就会输出输出什么数字,
why??
谢谢!


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2007-09-30 11:40 
头像

注册: 2007-08-22 17:36
帖子: 461
地址: 澳门
送出感谢: 0 次
接收感谢: 0 次
#include<iostream>
int main()
{
int b[7];
std::cout<<b[7]<<std::endl;
return 0;
}

应该是访问了没有分配给数组的内存空间。上面的结果中b[7]访问了不属于数组的内存空间,读取了一个无用的值,这个值是以前使用这个内存单元时保存的值。


_________________
我很敏捷,我是网上的蜘蛛;我很茫然,我是网中的猎物!
欢迎到我的Blog※代码回音※


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2007-09-30 11:42 

注册: 2007-09-14 19:51
帖子: 972
送出感谢: 0 次
接收感谢: 0 次
你没理解我的意思
我的问题在第二个代码上


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2007-09-30 11:48 

注册: 2006-10-06 21:10
帖子: 57
送出感谢: 0 次
接收感谢: 0 次
可能 a 正好放在 b[]的后面 。所以b[7] 引用了a的内容。(stack 是倒着长的,所以后面的变量的地址反而小)

如果改变一下编译选项,比如加个 -O,你说的效果可能就没有了。


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2007-09-30 11:51 

注册: 2007-09-14 19:51
帖子: 972
送出感谢: 0 次
接收感谢: 0 次
forcotton 写道:
可能 a 正好放在 b[]的后面 。所以b[7] 引用了a的内容。(stack 是倒着长的,所以后面的变量的地址反而小)

如果改变一下编译选项,比如加个 -O,你说的效果可能就没有了。

果然是这样
谢谢


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2007-10-01 5:30 

注册: 2007-09-07 3:08
帖子: 38
送出感谢: 0 次
接收感谢: 0 次
这有什么不好理解的?
代码:
int main()
{
    const int a=7;
    int b[a];
    std::cout<<b[a]<<std::endl;
    return 0;
}
如果当前esp是0x100000
---------asm
push   ebp
mov   ebp, esp
sub   esp, 4         ;int a ,a的地址  = esp = 0x0FFFFC
mov   eax, 7         ;
mov   SS:[esp], eax      ;a = 7
sub   esp, 4 * eax      ;int b[a], b 的地址  = b[0]的地址 = esp = 0x0FFFE0
mov   eax, SS:[esp + 4 * eax]   ;ebp + 0x1C = 0x0FFFFC = a的地址
...

所以显示的是a的值

至于第一个例子显示的应该是ebp的值,以为在int b[7]前入栈的是ebp


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2007-10-01 13:00 

注册: 2007-09-14 19:51
帖子: 972
送出感谢: 0 次
接收感谢: 0 次
可是我看不懂汇编呀


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2007-10-01 18:27 
头像

注册: 2005-08-25 13:58
帖子: 808
地址: ustc
送出感谢: 0 次
接收感谢: 0 次
me 写道:
可是我看不懂汇编呀

因为参数是压到栈里面的,栈是从高地址向低地址方向长的,变量在栈里面的分布如下:

高地址
a
b[6]
b[5]
.
.
.
b[0]
低地址


_________________
爱喝真猪奶茶的夜鸣猪


页首
 用户资料  
 
9 楼 
 文章标题 : Re: [问题]数组下标越界发现的问题
帖子发表于 : 2007-10-02 0:25 
头像

注册: 2006-05-03 0:39
帖子: 8273
地址: المريخ
送出感谢: 0 次
接收感谢: 1
me 写道:
编译下列代码并运行会输出不固定的数字
代码:
#include<iostream>
int main()
{
    int b[7];
    std::cout<<b[7]<<std::endl;
    return 0;
}



但是编译下列代码会并运行会输出:7
代码:
#include<iostream>
int main()
{
    const int a=7;
    int b[a];
    std::cout<<b[a]<<std::endl;
    return 0;
}


把上面的代码中的 a改成什么数字,运行结果就会输出输出什么数字,
why??
谢谢!

b和a都在堆栈中分配空间。在堆栈的分配中,是往高到低来分配的。在这里,首先往低处给a分配空间,然后紧挨着给b分配空间,这样刚好a就在b的最后(也就是[a]的位置),所以当你用b[a]的时候,它就访问到的是a的值了。


_________________
PHP是最好的语言!不服来战!


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 9 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译