什么是分段故障?它在C和C++中不同吗?分段错误和悬挂指针是如何关联的?
当前回答
分段错误是由对进程未在其描述符表中列出的页面的请求,或对进程已列出的页面(例如,只读页面上的写入请求)的无效请求引起的。
悬空指针是指可能指向或不指向有效页,但确实指向“意外”内存段的指针。
其他回答
分段错误的简单含义是,您试图访问一些不属于您的内存。当我们尝试在只读内存位置读取和/或写入任务或尝试释放内存时,会发生分段错误。换句话说,我们可以将其解释为某种内存损坏。
下面我提到了程序员所犯的导致分段错误的常见错误。
以错误的方式使用scanf()(忘记放&)。
int num;
scanf("%d", num);// must use &num instead of num
以错误的方式使用指针。
int *num;
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
修改字符串文字(指针尝试写入或修改只读内存。)
char *str;
//Stored in read only part of data segment
str = "GfG";
//Problem: trying to modify read only memory
*(str+1) = 'n';
尝试通过已释放的地址进行访问。
// allocating memory to num
int* num = malloc(8);
*num = 100;
// de-allocated the space allocated to num
free(num);
// num is already freed there for it cause segmentation fault
*num = 110;
堆栈溢出-:堆栈内存不足访问数组超出界限'使用printf()和scanf()时使用错误的格式说明符'
值得注意的是,分段错误不是由直接访问另一个进程内存引起的(这是我有时听到的),因为这根本不可能。对于虚拟内存,每个进程都有自己的虚拟地址空间,无法使用任何指针值访问另一个地址空间。例外情况可能是共享库,它们是映射到(可能)不同虚拟地址的相同物理地址空间,内核内存甚至在每个进程中以相同的方式映射(我认为是为了避免系统调用时的TLB刷新)。还有像shmat这样的东西;)-这些就是我所说的“间接”访问。然而,我们可以检查它们通常位于距离过程代码很远的地方,并且我们通常能够访问它们(这就是它们存在的原因,尽管以不正确的方式访问它们会产生分段错误)。
尽管如此,如果以不正确的方式访问我们自己的(进程)内存(例如试图写入不可写空间),可能会发生分段错误。但最常见的原因是访问虚拟地址空间中根本没有映射到物理地址空间的部分。
所有这些都与虚拟内存系统有关。
当进程(正在运行的程序实例)试图访问其他进程正在使用的只读内存地址或内存范围或访问不存在的(无效的)内存地址时,会发生分段错误。悬挂引用(指针)问题意味着试图访问内容已从内存中删除的对象或变量,例如:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
分段故障也是由硬件故障引起的,在这种情况下是RAM存储器。这是不太常见的原因,但如果您在代码中没有发现错误,也许memtest可以帮助您。
在这种情况下,解决方案是更改RAM。
编辑:
这里有一个参考:硬件分割故障
当一个进程(正在运行的程序实例)试图访问另一个进程正在使用的只读内存地址或内存范围或访问不存在的内存地址时,会发生分段错误。
seg错误,当类型不匹配时