什么是分段错误?

什么是分段错误? C和C ++有什么不同? 分段错误和悬挂指针如何相关?


分段错误是由于访问“不属于你”的内存而导致的一种特定类型的错误。它是一种助手机制,可以防止破坏内存并引入难以调试的内存错误。 每当你遇到段错误时,你都知道你正在做的是内存错误 - 访问已被释放的变量,写入内存的只读部分等等。在大多数语言中,分段错误基本上是一样的,内存管理,C和C ++中的段错误之间没有主要区别。

至少在C(++)等低级语言中,有许多方法可以获得段错误。 获取段错误的常用方法是取消引用空指针:

int *p = NULL;
*p = 1;

当您尝试写入标记为只读的部分内存时,会发生另一段错误:

char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault

悬挂指针指向一个不再存在的事物,如下所示:

char *p = NULL;
{
    char c;
    p = &c;
}
// Now p is dangling

指针p悬挂,因为它指向块结束后不再存在的字符变量c 。 而当你试图解引用悬挂指针时(比如*p='A' ),你可能会遇到段错误。


值得注意的是,分段错误不是由直接访问另一个进程内存引起的(这是我有时听到的),因为这是不可能的。 使用虚拟内存,每个进程都有自己的虚拟地址空间,并且无法使用任何指针值访问另一个进程。 例外是共享库,这些共享库映射到(可能)不同的虚拟地址和内核内存,它们在每个进程中都以相同的方式映射(为了避免系统调用时TLB刷新,我认为)。 而像shmat这样的东西) - 这些就是我所谓的“间接”访问。 但是,可以检查它们通常远离流程代码,我们通常能够访问它们(这就是为什么它们在那里,但以不正确的方式访问它们将产生分段错误)。

但是,如果以不正确的方式访问我们自己的(进程)内存(例如尝试写入不可写入的空间),则会发生分段错误。 但最常见的原因是访问虚拟地址空间的一部分,它根本没有映射到物理地址空间。

而这一切都与虚拟内存系统有关。


分段错误是由进程未在其描述符表中列出的页面请求引起的,也可能是它列出的页面的无效请求(例如,在只读页面上的写入请求)。

悬挂指针是一个指针,可能指向或不指向有效页面,但会指向“意外”内存段。

链接地址: http://www.djcxy.com/p/43873.html

上一篇: What is a segmentation fault?

下一篇: What is an undefined reference/unresolved external symbol error and how do I fix it?