什么是分段故障?它在C和C++中不同吗?分段错误和悬挂指针是如何关联的?
当前回答
当一个进程(正在运行的程序实例)试图访问另一个进程正在使用的只读内存地址或内存范围或访问不存在的内存地址时,会发生分段错误。
seg错误,当类型不匹配时
其他回答
简单地说:分段故障是操作系统向程序发送信号表示已检测到非法内存访问,并正在提前终止程序以防止防止内存损坏。
维基百科的Segmentation_fault页面对其进行了很好的描述,只是指出了原因和原因。查看wiki以获得详细描述。
在计算中,分段故障(通常简称为segfault)或访问违规是由具有内存保护的硬件引起的故障,通知操作系统(OS)内存访问违规。
以下是分段故障的一些典型原因:
取消引用NULL指针–这是内存管理硬件的特殊情况试图访问不存在的内存地址(在进程的地址空间之外)试图访问程序无权访问的内存(例如进程上下文中的内核结构)试图写入只读内存(如代码段)
这些通常由导致无效内存访问的编程错误引起:
取消引用或分配给未初始化的指针(指向随机内存地址的通配符指针)取消引用或分配给已释放指针(悬空指针,指向已释放/解除分配/删除的内存)缓冲区溢出。堆栈溢出。试图执行未正确编译的程序。(尽管存在编译时错误,某些编译器仍会输出可执行文件。)
值得注意的是,分段错误不是由直接访问另一个进程内存引起的(这是我有时听到的),因为这根本不可能。对于虚拟内存,每个进程都有自己的虚拟地址空间,无法使用任何指针值访问另一个地址空间。例外情况可能是共享库,它们是映射到(可能)不同虚拟地址的相同物理地址空间,内核内存甚至在每个进程中以相同的方式映射(我认为是为了避免系统调用时的TLB刷新)。还有像shmat这样的东西;)-这些就是我所说的“间接”访问。然而,我们可以检查它们通常位于距离过程代码很远的地方,并且我们通常能够访问它们(这就是它们存在的原因,尽管以不正确的方式访问它们会产生分段错误)。
尽管如此,如果以不正确的方式访问我们自己的(进程)内存(例如试图写入不可写空间),可能会发生分段错误。但最常见的原因是访问虚拟地址空间中根本没有映射到物理地址空间的部分。
所有这些都与虚拟内存系统有关。
分段错误是由于访问“不属于您的”内存而导致的一种特定错误。它是一种帮助机制,可以防止损坏内存并引入难以调试的内存错误。每当你得到一个segfault时,你就知道你在内存方面出了问题——访问一个已经被释放的变量,写入内存的只读部分,等等。在大多数语言中,segfault基本上是一样的,这会让你陷入内存管理的困境,在C和C++中segfault之间没有主要区别。
有很多方法可以获得segfault,至少在C(++)等较低级别的语言中是如此。获取segfault的常见方法是取消引用空指针:
int *p = NULL;
*p = 1;
当您尝试写入标记为只读的内存部分时,会发生另一个segfault:
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')时,可能会得到一个segfault。
在计算中,分段故障或访问违规是由具有存储器保护的硬件引起的故障或故障状况,通知操作系统该软件已尝试访问内存的受限区域-维基百科
您可能正在使用错误的数据类型访问计算机内存。您的案例可能如下所示:
#include <stdio.h>
int main(int argc, char *argv[]) {
char A = 'asd';
puts(A);
return 0;
}
“asd”->是一个字符链,而不是单个字符的char数据类型。因此,将其存储为字符会导致分段错误。在错误的位置存储一些数据。
将这个字符串或字符链存储为单个字符是为了在圆孔中插入一个方形钉。
由于信号:分段故障(11)而终止
塞格姆。错误与尝试在水下呼吸是一样的,你的肺不适合这样。为一个整数保留内存,然后尝试将其作为另一种数据类型进行操作,这根本不起作用。