什么是段错误?在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'
),很可能会导致段错误。
int main()
{
char *p = 0;
{
char c = 'x';
p = &c;
}
printf( "%c\n",*p);
return 0;
}
使用gcc或其他几个编译器都“似乎”可以工作。编译时没有警告,也不会导致段错误。这是因为‘}’离开范围时,并不会实际删除数据,只是将其标记为空闲状态以便再次使用。该代码可能在生产系统上运行多年,直到您更改代码的另一部分、更改编译器或发生其他问题,程序才会崩溃。 - Chris Huang-Leaver分段错误是由于进程请求的页面未在其描述符表中列出,或者请求一个已列出但不合法的页面(例如,在只读页面上进行写入请求)。
悬空指针是指可能指向有效页面,但指向“意外”的内存段的指针。
说实话,正如其他帖子所提到的,维基百科有一篇非常好的文章请在那里查看.这种类型的错误非常常见,通常被称为访问冲突或通用保护错误。
在允许使用指针的任何语言中,它们都没有任何区别。 这些类型的错误通常是由于指针在以下情况下引起的:
段错误也可能由硬件故障引起,这种情况下是因为RAM内存问题。这是较少见的原因之一,但如果您在代码中找不到错误,也许可以通过运行内存测试来帮助解决。
在这种情况下,解决方案是更换RAM。
编辑:
这里有一个参考链接:硬件引起的段错误
维基百科的“段错误”页面提供了一个非常好的描述,仅指出了其中的原因和理由。详细信息请查看维基百科。
在计算机中,段错误(通常缩写为 segfault)或访问冲突是由具备内存保护功能的硬件引发的故障,通知操作系统(OS)存在内存访问违规。
以下是一些典型的段错误原因:
这些又往往是由导致非法访问内存的编程错误引起的:
解除引用或分配给未初始化的指针(野指针,它指向随机的内存地址)
解除引用或分配给已释放指针(悬空指针,它指向已被释放/取消分配/删除的内存)
缓冲区溢出。
堆栈溢出。
尝试执行无法正确编译的程序。(一些编译器将在存在编译时错误的情况下输出可执行文件。)
分段错误发生在进程(程序的运行实例)试图访问只读内存地址或被其他进程使用的内存范围,或者访问不存在(无效)的内存地址时。 悬空引用(指针)问题意味着试图访问已经从内存中删除内容的对象或变量,例如:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
NullPointerException
。 - Raedwald