Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在哪种情况下C会抛出分段错误?_C_Segmentation Fault_Coredump - Fatal编程技术网

在哪种情况下C会抛出分段错误?

在哪种情况下C会抛出分段错误?,c,segmentation-fault,coredump,C,Segmentation Fault,Coredump,我知道在访问超出范围的阵列时: int arr[2]; arr[3] = 10; C将在运行时抛出一个分段错误(内核转储) 但是,C不会用其他东西检查越界访问,例如strcpy() 我想确切地知道哪些情况会导致分割错误,哪些不会。我找到了答案。只有当我们访问操作系统没有分配给进程的内存时,才会出现分段错误。但有时,在越界访问中,我们可能仍然在程序的分配内存中,因此不会给我们分段错误-在这种情况下,它会给我们垃圾值。访问任何您不拥有的内存是未定义的行为。这仅仅意味着C标准根本不需要编译器来处理

我知道在访问超出范围的阵列时:

int arr[2]; 
arr[3] = 10;
C将在运行时抛出一个
分段错误(内核转储)

但是,C不会用其他东西检查越界访问,例如
strcpy()


我想确切地知道哪些情况会导致分割错误,哪些不会。

我找到了答案。只有当我们访问操作系统没有分配给进程的内存时,才会出现分段错误。但有时,在越界访问中,我们可能仍然在程序的分配内存中,因此不会给我们分段错误-在这种情况下,它会给我们垃圾值。

访问任何您不拥有的内存是未定义的行为。这仅仅意味着C标准根本不需要编译器来处理这种情况

由于C努力成为一种高效的语言,编译器很少(曾经?)会发出机器代码来对这些东西进行运行时检查。如果在编译时可以检测到违规行为,他们可能会也可能不会发出警告或错误

其本质是:您在运行时收到的任何错误消息(包括segfault)通常都来自操作系统。在较旧的系统/OSs上,甚至今天在较小的(嵌入式)系统上,这种内存管理以前/现在都不可用,内存访问冲突可能会使整个系统崩溃,可能是在原始冲突发生很久之后。否则什么也不会发生。或者更阴险的事情,比如数据损坏

因此,很高兴拥有现代操作系统虚拟内存管理系统的安全网,但不要依赖它们来防止编程错误造成更大的损害,或者首先检测此类错误

您还应该尝试一下valgrind之类的工具,它为您的程序提供了大量的运行时分析和错误检测;这样可以学到很多东西


顺便说一句:正如selbie在评论中指出的,您的代码可能会覆盖函数堆栈帧或激活记录的一部分。原因是大多数机器上的堆栈向下增长(新内存分配在较小的地址),但数组索引向上移动。许多编译器都包含使用“堆栈金丝雀”进行编译的选项,该选项可以在运行时检测堆栈损坏。在开发和测试期间,这是一项非常有用的功能,还提供了一些防御恶意软件的功能,这些恶意软件试图利用缓冲区溢出进行攻击。

访问您不拥有的内存是非常困难的。您希望这会导致seg故障,这表明您需要查找并修复一个问题。但是“未定义的行为”的意思就是。。任何事情都可能发生,包括没有seg错误和代码运行良好的外观。问题中的示例导致seg错误的原因是您可能会损坏堆栈。当函数返回时会发生崩溃。如果为该数组分配了
malloc
,然后插入了一个超出范围的值,则不一定能可靠地命中seg故障。