C++ 在C+中,索引离开数组边界后,会出现分段错误+;

C++ 在C+中,索引离开数组边界后,会出现分段错误+;,c++,arrays,debugging,segmentation-fault,C++,Arrays,Debugging,Segmentation Fault,我有以下代码: #include <cstdio> int foo[100]; int main() { for(int i=0;i<10000;i++) foo[i]=10000; } 现在,我知道是语句foo[I]=10000导致了错误,但我声明foo的大小仅为100。为什么在错误发生之前,i的值会这么大 感谢您的解释。在您更新问题后,您发布了以下内容: 当i=100时 使用原始数组时,没有边界检查;这是你和用户必须负责的事情。如果要为您执行自动边界检查以防止

我有以下代码:

#include <cstdio>

int foo[100];

int main()
{
for(int i=0;i<10000;i++)
    foo[i]=10000;
}
现在,我知道是语句
foo[I]=10000
导致了错误,但我声明foo的大小仅为
100
。为什么在错误发生之前,
i
的值会这么大


感谢您的解释。

在您更新问题后,您发布了以下内容:

i=100时

使用原始数组时,没有边界检查;这是你和用户必须负责的事情。如果要为您执行自动边界检查以防止此越界内存分段错误,则应根据需要使用任何标准容器,如
std::vector
std::list
std::set
等。如果需要使用数组索引表示法,则可以使用
std::vector
。或来自任何其他库(如
boost
)的任何其他
向量

编辑


要解决此问题,您必须将数组的大小从
100
增加到
10000
,或者必须从
i减少循环的条件将元素访问超出边界是“未定义行为”,这意味着任何事情都可能发生。“直到错误发生很久才报告任何问题”是“任何事情”的一种可能结果。不幸的是,未定义的行为不一定会导致明显的问题。因为 Que[]/Cord>是数据段的一部分,所以在有一个有效的内存位置之前,可以读取一个无效的内存位置。C++运行在“只使用你所使用的”哲学的基础上。一个正确的程序没有缓冲区溢出,所以检查缓冲区溢出是他们不必支付的惩罚。因此会进行零检查,程序将继续运行,直到可能由溢出导致的某种情况使其停止。请使用而不是普通数组,并使用而不是下标运算符。这样,当越过边界时,您将得到一个异常。我不认为这是重复的,因为链接的答案没有回答问题,这就是为什么在偏移量4080之前没有错误。仅仅说“这是未定义的行为”并不能回答问题,就像“问:为什么天空是蓝色的?答:因为它不是黄色的”OP似乎在问为什么错误发生在i=4080而不是i=100,而不是为什么错误发生一样。@MilesBudnek可能,但前者应该在后者之前显而易见,任何对越界错误不确定的人都不应该访问大于索引数组大小的数组索引。但是,如果他关心<代码> i=4080 < /代码>,那么他需要考虑的是,它是一个32位的系统,那么<代码> int >代码>类型应该是4字节。那么
4 x 4080=16320字节
在32位系统上,正常的页面或扇区大小是多少?@MilesBudnek因此,当您在页面文件的末尾走到这一步时;您开始体验缓存未命中和其他事情;它们还可能导致seg故障。基本上,他是在践踏不属于该数组的内存,因为它不是或者它最初不是为它保留的。
[New Thread 23684.0x59b4]
[New Thread 23684.0x5c0c]
[New Thread 23684.0x541c]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401564 in main () at C:\Users\DARREN\Documents\Visual Studio 
2017\Projects\Untitled1.cpp:9
warning: Source file is more recent than executable.
9       }
(gdb) print i
$1 = 4080
(gdb)
int foo[100];

int main()
{
for(int i=0;i<10000;i++)
    foo[i]=10000;
}
foo[i] = 10000; 
int var[10]; // Uninitialized

for ( int i = 0; i < 10; ++i ) {
    var[i] = 0; // Initialize all array indexes to 0
}