什么是分段故障?它在C和C++中不同吗?分段错误和悬挂指针是如何关联的?
当前回答
当一个进程(正在运行的程序实例)试图访问另一个进程正在使用的只读内存地址或内存范围或访问不存在的内存地址时,会发生分段错误。
seg错误,当类型不匹配时
其他回答
分段错误是由对进程未在其描述符表中列出的页面的请求,或对进程已列出的页面(例如,只读页面上的写入请求)的无效请求引起的。
悬空指针是指可能指向或不指向有效页,但确实指向“意外”内存段的指针。
简单地说:分段故障是操作系统向程序发送信号表示已检测到非法内存访问,并正在提前终止程序以防止防止内存损坏。
当程序试图访问不存在的内存位置,或试图以不允许的方式访问内存位置时,会发生分段错误或访问冲突。
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
这里i[1000]不存在,因此出现segfault。
分段故障的原因:
it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.
De-referencing NULL pointers – this is special-cased by memory management hardware.
Attempting to access a nonexistent memory address (outside process’s address space).
Attempting to access memory the program does not have rights to (such as kernel structures in process context).
Attempting to write read-only memory (such as code segment).
值得注意的是,分段错误不是由直接访问另一个进程内存引起的(这是我有时听到的),因为这根本不可能。对于虚拟内存,每个进程都有自己的虚拟地址空间,无法使用任何指针值访问另一个地址空间。例外情况可能是共享库,它们是映射到(可能)不同虚拟地址的相同物理地址空间,内核内存甚至在每个进程中以相同的方式映射(我认为是为了避免系统调用时的TLB刷新)。还有像shmat这样的东西;)-这些就是我所说的“间接”访问。然而,我们可以检查它们通常位于距离过程代码很远的地方,并且我们通常能够访问它们(这就是它们存在的原因,尽管以不正确的方式访问它们会产生分段错误)。
尽管如此,如果以不正确的方式访问我们自己的(进程)内存(例如试图写入不可写空间),可能会发生分段错误。但最常见的原因是访问虚拟地址空间中根本没有映射到物理地址空间的部分。
所有这些都与虚拟内存系统有关。
老实说,正如其他海报所提到的那样,维基百科在这方面有一篇很好的文章,所以看看吧。这种类型的错误非常常见,通常称为其他错误,如访问违规或一般保护故障。
它们在C、C++或任何其他允许指针的语言中都没有区别。这些类型的错误通常由以下指针引起:
在正确初始化之前使用在它们指向的内存被重新定位或删除后使用。在索引超出数组边界的索引数组中使用。这通常只在对传统数组或c字符串进行指针计算时发生,而不是基于STL/Boost的集合(在c++中)