首页
社区
课程
招聘
[求助]main外面和里面定义的区别
发表于: 2016-2-24 23:01 4843

[求助]main外面和里面定义的区别

2016-2-24 23:01
4843
初学者,望各位前辈指导

有两段简单的代码:
一,
#include <stdio.h>
#include <string.h>
char name[]="abcdefghijklmnopqrstuvwxyz";

void main()
{
       
        char output[8];
        strcpy(output,name);
        for(int i=0;i<8&&output[i];i++)
                printf("\\0x%x",output[i]);

}

二,

#include <stdio.h>
#include <string.h>

void main()
{
        char name[]="abcdefghijklmnopqrstuvwxyz";
        char output[8];
        strcpy(output,name);
        for(int i=0;i<8&&output[i];i++)
                printf("\\0x%x",output[i]);

}

一样的代码,只是定义name[]的位置不同,
请问为什么第一段会出错,而第二段不会出错呢?
在main外面定义和里面定义有什么区别呢?

谢谢各位

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 118
活跃值: (72)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
main也是一个函数。函数里面的变量统称局部变量,函数外面的叫全局变量。顾名思义。
2016-2-24 23:52
0
雪    币: 209
活跃值: (818)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
一个只在函数里面起作用,
一个在整个源文件里面都起作用,还能被其他的源文件引用!
2016-2-25 01:07
0
雪    币: 786
活跃值: (3435)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
4
二楼和三楼说的对,一个是全局,一个是局部。
然而你出现的问题并不是因为全局和局部的区别,而是因为output数组越界。
第一个会出错是正常的,因为越界了。
第二个不出错只能说是你运气好,因为越界了。
2016-2-25 09:05
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你两个里面的 i判断条件有问题。
2016-2-25 09:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
其实目的就是要他越界,但是为什么第二个不出错呢?搞不懂
2016-2-25 14:45
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
什么问题?
2016-2-25 14:47
0
雪    币: 1787
活跃值: (340)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
因为第二个的栈足够大,把name的一部分覆盖掉了。如果非DEBUG模式,不会崩溃。DEBUG版本因为有越界检测,会出一个断言
2016-2-25 15:31
0
雪    币: 786
活跃值: (3435)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
9
总的来说,两者都存在一个缓冲区溢出的问题,溢出之后覆盖了栈。
第一个覆盖的栈区导致ret的返回地址被覆盖了,所以出错。
第二个覆盖的是name的内存区域,所以程序不会崩溃,但是name的内容肯定是改变了。
2016-2-25 16:03
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢。

是不是说可以这样理解,在main外面定义和里面定义,所分配的内存中的地址是不一样的?所以覆盖的地方也不一样?
2016-2-26 13:36
0
雪    币: 786
活跃值: (3435)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
11
差不多这个意思吧
2016-2-26 14:37
0
雪    币: 1176
活跃值: (1264)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
12
楼上说的对
2016-2-26 14:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
仔细想想,也不对

位置不同的是name这个参数,而output的位置没变(都是在main里面定义的);
而这里是使用name来覆盖output的,也就是说,name的位置变不变跟output没关系啊?为什么两次返回的结果不同呢?

举个例子,name相当于女朋友,main外面定义的name相当于北京的女朋友,main里面定义的name相当于上海的女朋友,但是我(相当于output)一直是我,没变过(一直都是在main里面定义的),为什么上海的女朋友来我家就愿意跟我打啵,北京的女朋友来我家就不愿意呢?(外面的name覆盖output会报错,里面的name覆盖output就不会报错)

2016-2-26 14:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
这例子好像不太恰当。。。。但各位应该能明白我意思吧
2016-2-26 14:53
0
雪    币: 1392
活跃值: (5207)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
15
影响其实有很多。这个和编译器以及优化方式有关。你换编译器编译。可能第二个又出错了。

你的
你的name若在里面
char name[]
char output[8];
name和output是连在一起的一块内存
假设栈name地址比output高那么往output里面写。溢出就覆盖了name的前面部分。这时候不会崩溃。
假设name地址比output低。你写溢出就覆盖了返回的eip就崩溃。

在外面的话如果覆盖了eip 一定崩溃
具体反汇编看一起才能确定是什么情况。我用VS2008测试。都会崩溃
2016-2-26 16:22
0
雪    币: 786
活跃值: (3435)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
16
橘生淮南则为橘,生于淮北则为枳。
建议debug编译第二个代码,在调试状态观察一下name的内存变化。
这种问题别人告诉你的,你未必能理解。还是要自己观察一下才明白。
2016-2-26 16:26
0
雪    币: 103
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
这个例子。。。。。这问题反汇编一下就知道问题
2016-2-26 18:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
[QUOTE=IamHuskar;1417082]影响其实有很多。这个和编译器以及优化方式有关。你换编译器编译。可能第二个又出错了。

你的
你的name若在里面
char name[]
char output[8];
name和output是连在一起的一块内存
假设栈name地址比output高那么往output里面写。溢出就覆盖了...[/QUOTE]

感谢! 这下明白了!
2016-2-26 22:51
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
ALT+8
2016-2-27 17:58
0
游客
登录 | 注册 方可回帖
返回
//