关于 C 语言中 a[10] = 5 的作用

时间:2021-11-04 01:59:22
int a[10];
a[10] = 5;
C编译通过,通过原因是 C语言没有地址保护机制。

问题是,a[10] = 5; 这句话的作用到底是什么?

106 个解决方案

#1


没有意义吧

#2


没有上下文 不好说
关于 C 语言中 a[10] = 5 的作用

#3


c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

#4


简单的理解就是为a[0]赋值为5啊.哈哈

#5


关于 C 语言中 a[10] = 5 的作用埋地雷

#6


*(a + 10) = 5;

#7


将数组中第11个数等于5

#8


数组越界了 编译的时候不检查数组边界的

#9


该回复于2011-12-27 15:01:15被版主删除

#10


数组越界了。

C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。

#11


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

#12


将数组之后一个int大小的内存值改变为5,由于是数组越界赋值,如果数组之后正好是其他有意义的内容(比如一个int变量,用1,2,3,4,5来区分不同的程序执行流程,即switch),就会改变了程序的执行流程,通常情况是直接导致程序崩溃。也有人利用这种情况对程序进行溢出攻击

#13


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#14


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#15


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#16


引用楼主 jhlxxxx 的回复:
int a[10];
a[10] = 5;
C编译通过,通过原因是 C语言没有地址保护机制。

问题是,a[10] = 5; 这句话的作用到底是什么?


c并不是没有越界检测机制,而是不要求、不强制越界检测机制的实现,如果有哪个环境实现了越界检测,那也是符合标准的行为。因为c/c++的宗旨之一,是给予程序员足够的*度,不过多替程序员做决定,但是程序员要为自己的行为负责。

#17


非法的操作

#18


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#19


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#20


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#21


是数组第11个元素值为5,也有可能是报错。

#22


使代码不可移植,并且为程序埋下一个可能难以定位的bug。

#23


很明显的数组越界了。
给数组后面的四个字节赋值为5.
程序很可能就这里挂了。。。。

#24



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}



output:
0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6

懂了,谢谢大家,结贴。

#25



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}


0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6


懂了,结贴

#26



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}


0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6

#27


但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a[10]有可能访问的是c,也有可能是b。这得看编译器怎么在函数栈里拍不局部变量了。
2.该数组周围没有相邻变量
   这个就不好说了,有可能是随机值。

总之这个和编译器关系很大。VC6,VS2005,VS2010都会有区别,不同编译选项也会有区别。编译优化也会对他有影响。

可以看下我这篇文章,我这里讨论了一个相关问题:
http://blog.csdn.net/shyandsy/article/details/7060638

#28


该回复于2011-12-28 09:25:57被版主删除

#29


C语言优秀就优秀在这种地方,用C语言的都是成年人,保护个什么劲,你进错地址你怪谁?

#30


人才
引用 11 楼 zhao4zhong1 的回复:
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸……

#31


27楼分析的很有道理.

#32


简单的说a[0]-a[9]这10个元素是受保护的,而a[10]是不受保护的

#33


引用 27 楼 shyandsy 的回复:
但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a……

对!一个数据越界,会影响到其它变量,如果被影响的是指针的话,free掉时出现段错误,但问题却不是指针问题,找bug很难。。。

#34


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++++++++++++++++++++++++

#35


6L正解 -

#36


引用 33 楼 liuchao35758600 的回复:
引用 27 楼 shyandsy 的回复:

但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
那么你写a[10]=x 就等于改变了你你定义的某个变量的值
比如:
int c;
int a[10];
int c;
那么你用a……

对!一个数……


++
制造无名段错误

#37


10个小朋友,由你带领,你从数字 0 挨个编号,到数字 9 就编号完了。我现在说:“我有个东西,需要给你们那编号为 10 的小朋友”。然后我就走了,你会怎么处理?

#38


将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错

#39


C并没有vb那样的安全数组,数组名实际是元素的首地址,在内部并没有保留数组长度的任何信息,访问数组单元是类似指针递增方式访问的,它怎么可能做地址越界检查?如果数组下标是从变量中取值,只有运行时才知道下标是多大,编译器也没法检查。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。

#40


数组越界,可能会引起程序崩溃

#41


考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用.

#42


在a[9]后面的四个字节里存进5.越界很危险...

#43


非法访问,越界了

#44


引用 38 楼 wenjavac 的回复:
将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错


debug有预留空间的

#45


引用 27 楼 shyandsy 的回复:
但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a……

有道理

#46


用了就太混乱了。。

#47


就是把内存里 a[9]后一个内存空间赋值为10,
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧

建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了

#48


考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用

#49


出来混的,迟早有一天要还的,伏笔啊

#50


该回复于2011-12-30 09:04:20被版主删除

#1


没有意义吧

#2


没有上下文 不好说
关于 C 语言中 a[10] = 5 的作用

#3


c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

#4


简单的理解就是为a[0]赋值为5啊.哈哈

#5


关于 C 语言中 a[10] = 5 的作用埋地雷

#6


*(a + 10) = 5;

#7


将数组中第11个数等于5

#8


数组越界了 编译的时候不检查数组边界的

#9


该回复于2011-12-27 15:01:15被版主删除

#10


数组越界了。

C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。

#11


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

#12


将数组之后一个int大小的内存值改变为5,由于是数组越界赋值,如果数组之后正好是其他有意义的内容(比如一个int变量,用1,2,3,4,5来区分不同的程序执行流程,即switch),就会改变了程序的执行流程,通常情况是直接导致程序崩溃。也有人利用这种情况对程序进行溢出攻击

#13


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#14


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#15


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..

++

#16


引用楼主 jhlxxxx 的回复:
int a[10];
a[10] = 5;
C编译通过,通过原因是 C语言没有地址保护机制。

问题是,a[10] = 5; 这句话的作用到底是什么?


c并不是没有越界检测机制,而是不要求、不强制越界检测机制的实现,如果有哪个环境实现了越界检测,那也是符合标准的行为。因为c/c++的宗旨之一,是给予程序员足够的*度,不过多替程序员做决定,但是程序员要为自己的行为负责。

#17


非法的操作

#18


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#19


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#20


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++

#21


是数组第11个元素值为5,也有可能是报错。

#22


使代码不可移植,并且为程序埋下一个可能难以定位的bug。

#23


很明显的数组越界了。
给数组后面的四个字节赋值为5.
程序很可能就这里挂了。。。。

#24



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}



output:
0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6

懂了,谢谢大家,结贴。

#25



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}


0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6


懂了,结贴

#26



#include <stdio.h>

int main(int argc, char *argv[]) {
int a[10];
printf("%p\n", &a);
a[11] = 6;
printf("%p\n", &a);
printf("%p\n", &a[11]);
printf("%d\n", a[11]);
}


0x7fff6a33eba0
0x7fff6a33eba0
0x7fff6a33ebcc
6

#27


但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a[10]有可能访问的是c,也有可能是b。这得看编译器怎么在函数栈里拍不局部变量了。
2.该数组周围没有相邻变量
   这个就不好说了,有可能是随机值。

总之这个和编译器关系很大。VC6,VS2005,VS2010都会有区别,不同编译选项也会有区别。编译优化也会对他有影响。

可以看下我这篇文章,我这里讨论了一个相关问题:
http://blog.csdn.net/shyandsy/article/details/7060638

#28


该回复于2011-12-28 09:25:57被版主删除

#29


C语言优秀就优秀在这种地方,用C语言的都是成年人,保护个什么劲,你进错地址你怪谁?

#30


人才
引用 11 楼 zhao4zhong1 的回复:
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸……

#31


27楼分析的很有道理.

#32


简单的说a[0]-a[9]这10个元素是受保护的,而a[10]是不受保护的

#33


引用 27 楼 shyandsy 的回复:
但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a……

对!一个数据越界,会影响到其它变量,如果被影响的是指针的话,free掉时出现段错误,但问题却不是指针问题,找bug很难。。。

#34


引用 3 楼 mingliang1212 的回复:
c语言的确没有下标范围检测..

a[10]=5;的作用是为程序崩溃埋下深深的伏笔..


++++++++++++++++++++++++

#35


6L正解 -

#36


引用 33 楼 liuchao35758600 的回复:
引用 27 楼 shyandsy 的回复:

但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
那么你写a[10]=x 就等于改变了你你定义的某个变量的值
比如:
int c;
int a[10];
int c;
那么你用a……

对!一个数……


++
制造无名段错误

#37


10个小朋友,由你带领,你从数字 0 挨个编号,到数字 9 就编号完了。我现在说:“我有个东西,需要给你们那编号为 10 的小朋友”。然后我就走了,你会怎么处理?

#38


将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错

#39


C并没有vb那样的安全数组,数组名实际是元素的首地址,在内部并没有保留数组长度的任何信息,访问数组单元是类似指针递增方式访问的,它怎么可能做地址越界检查?如果数组下标是从变量中取值,只有运行时才知道下标是多大,编译器也没法检查。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。

#40


数组越界,可能会引起程序崩溃

#41


考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用.

#42


在a[9]后面的四个字节里存进5.越界很危险...

#43


非法访问,越界了

#44


引用 38 楼 wenjavac 的回复:
将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错


debug有预留空间的

#45


引用 27 楼 shyandsy 的回复:
但从语言来说
a[10] 定义了10个单位大小的连续栈空间 [0,9]
但是具体a[10]位置是什么,不同编译器,不同代码都不一样

说2种情况
1.是你定义的某个相邻局部变量
      那么你写a[10]=x 就等于改变了你你定义的某个变量的值
     比如:
       int c;
       int a[10];
       int c;
   那么你用a……

有道理

#46


用了就太混乱了。。

#47


就是把内存里 a[9]后一个内存空间赋值为10,
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧

建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了

#48


考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用

#49


出来混的,迟早有一天要还的,伏笔啊

#50


该回复于2011-12-30 09:04:20被版主删除