a[10] = 5;
C编译通过,通过原因是 C语言没有地址保护机制。
问题是,a[10] = 5; 这句话的作用到底是什么?
106 个解决方案
#1
没有意义吧
#2
没有上下文 不好说
#3
c语言的确没有下标范围检测..
a[10]=5;的作用是为程序崩溃埋下深深的伏笔..
a[10]=5;的作用是为程序崩溃埋下深深的伏笔..
#4
简单的理解就是为a[0]赋值为5啊.哈哈
#5
埋地雷
#6
*(a + 10) = 5;
#7
将数组中第11个数等于5
#8
数组越界了 编译的时候不检查数组边界的
#9
#10
数组越界了。
C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。
C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。
#11
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
#12
将数组之后一个int大小的内存值改变为5,由于是数组越界赋值,如果数组之后正好是其他有意义的内容(比如一个int变量,用1,2,3,4,5来区分不同的程序执行流程,即switch),就会改变了程序的执行流程,通常情况是直接导致程序崩溃。也有人利用这种情况对程序进行溢出攻击
#13
++
#14
++
#15
++
#16
c并不是没有越界检测机制,而是不要求、不强制越界检测机制的实现,如果有哪个环境实现了越界检测,那也是符合标准的行为。因为c/c++的宗旨之一,是给予程序员足够的*度,不过多替程序员做决定,但是程序员要为自己的行为负责。
#17
非法的操作
#18
++
#19
++
#20
++
#21
是数组第11个元素值为5,也有可能是报错。
#22
使代码不可移植,并且为程序埋下一个可能难以定位的bug。
#23
很明显的数组越界了。
给数组后面的四个字节赋值为5.
程序很可能就这里挂了。。。。
给数组后面的四个字节赋值为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
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
#29
C语言优秀就优秀在这种地方,用C语言的都是成年人,保护个什么劲,你进错地址你怪谁?
#30
人才
#31
27楼分析的很有道理.
#32
简单的说a[0]-a[9]这10个元素是受保护的,而a[10]是不受保护的
#33
对!一个数据越界,会影响到其它变量,如果被影响的是指针的话,free掉时出现段错误,但问题却不是指针问题,找bug很难。。。
#34
++++++++++++++++++++++++
#35
6L正解 -
#36
++
制造无名段错误
#37
10个小朋友,由你带领,你从数字 0 挨个编号,到数字 9 就编号完了。我现在说:“我有个东西,需要给你们那编号为 10 的小朋友”。然后我就走了,你会怎么处理?
#38
将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错
#39
C并没有vb那样的安全数组,数组名实际是元素的首地址,在内部并没有保留数组长度的任何信息,访问数组单元是类似指针递增方式访问的,它怎么可能做地址越界检查?如果数组下标是从变量中取值,只有运行时才知道下标是多大,编译器也没法检查。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。
#40
数组越界,可能会引起程序崩溃
#41
考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用.
#42
在a[9]后面的四个字节里存进5.越界很危险...
#43
非法访问,越界了
#44
debug有预留空间的
#45
有道理
#46
用了就太混乱了。。
#47
就是把内存里 a[9]后一个内存空间赋值为10,
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧
建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧
建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了
#48
考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用
#49
出来混的,迟早有一天要还的,伏笔啊
#50
#1
没有意义吧
#2
没有上下文 不好说
#3
c语言的确没有下标范围检测..
a[10]=5;的作用是为程序崩溃埋下深深的伏笔..
a[10]=5;的作用是为程序崩溃埋下深深的伏笔..
#4
简单的理解就是为a[0]赋值为5啊.哈哈
#5
埋地雷
#6
*(a + 10) = 5;
#7
将数组中第11个数等于5
#8
数组越界了 编译的时候不检查数组边界的
#9
#10
数组越界了。
C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。
C语言就像一把屠龙刀,很有杀伤力。
你要这把刀提供不误伤人的功能,如果有这个功能,那它还是屠龙刀吗?
那它强大的威力是不是被阉割了呢。
#11
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
#12
将数组之后一个int大小的内存值改变为5,由于是数组越界赋值,如果数组之后正好是其他有意义的内容(比如一个int变量,用1,2,3,4,5来区分不同的程序执行流程,即switch),就会改变了程序的执行流程,通常情况是直接导致程序崩溃。也有人利用这种情况对程序进行溢出攻击
#13
++
#14
++
#15
++
#16
c并不是没有越界检测机制,而是不要求、不强制越界检测机制的实现,如果有哪个环境实现了越界检测,那也是符合标准的行为。因为c/c++的宗旨之一,是给予程序员足够的*度,不过多替程序员做决定,但是程序员要为自己的行为负责。
#17
非法的操作
#18
++
#19
++
#20
++
#21
是数组第11个元素值为5,也有可能是报错。
#22
使代码不可移植,并且为程序埋下一个可能难以定位的bug。
#23
很明显的数组越界了。
给数组后面的四个字节赋值为5.
程序很可能就这里挂了。。。。
给数组后面的四个字节赋值为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
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
#29
C语言优秀就优秀在这种地方,用C语言的都是成年人,保护个什么劲,你进错地址你怪谁?
#30
人才
#31
27楼分析的很有道理.
#32
简单的说a[0]-a[9]这10个元素是受保护的,而a[10]是不受保护的
#33
对!一个数据越界,会影响到其它变量,如果被影响的是指针的话,free掉时出现段错误,但问题却不是指针问题,找bug很难。。。
#34
++++++++++++++++++++++++
#35
6L正解 -
#36
++
制造无名段错误
#37
10个小朋友,由你带领,你从数字 0 挨个编号,到数字 9 就编号完了。我现在说:“我有个东西,需要给你们那编号为 10 的小朋友”。然后我就走了,你会怎么处理?
#38
将5给了a[9]后面的单元,我用的VC,好像可以多越界2-3个,多了才会报错
#39
C并没有vb那样的安全数组,数组名实际是元素的首地址,在内部并没有保留数组长度的任何信息,访问数组单元是类似指针递增方式访问的,它怎么可能做地址越界检查?如果数组下标是从变量中取值,只有运行时才知道下标是多大,编译器也没法检查。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。
vb的安全数组则不同,它在内部保留数组本身的的信息。
如果要使用更安全的数组,用C去实现一个也并非难事。
#40
数组越界,可能会引起程序崩溃
#41
考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用.
#42
在a[9]后面的四个字节里存进5.越界很危险...
#43
非法访问,越界了
#44
debug有预留空间的
#45
有道理
#46
用了就太混乱了。。
#47
就是把内存里 a[9]后一个内存空间赋值为10,
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧
建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了
如果你这个内存空间恰好存的是有用的数据..你就等着在某个刹那出问题吧
建议赋值时一定要小心的检查是否越界
因为c语言没有数组越界检查
当然也可以选择用stl模板的vector,你这么赋值就会报错了
#48
考27L结合动手调试,看内存,看寄存器. 然后可再参考c陷阱与缺陷 语义陷阱3.6一节中"类似"情况造成无限循环来加深印象与理解. 如果是我没理解楼主的问题,忘楼主别鄙视我...因为我真不知道为什么要问这么赋值的作用
#49
出来混的,迟早有一天要还的,伏笔啊