什么是分段故障?它在C和C++中不同吗?分段错误和悬挂指针是如何关联的?
当前回答
有足够多的分段错误的定义,我想引用几个我在编程时遇到的例子,这可能看起来像是愚蠢的错误,但会浪费很多时间。
当printf中的参数类型不匹配时,在以下情况下可能会出现分段错误:
#include <stdio.h>
int main(){
int a = 5;
printf("%s",a);
return 0;
}
输出:分段故障(SIGSEGV)
当您忘记为指针分配内存时,请尝试使用它。
#include <stdio.h>
typedef struct{
int a;
} myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
输出:分段故障(SIGSEGV)
其他回答
“分段错误”表示您试图访问无法访问的内存。
第一个问题是你的论点。main函数应该是int main(int argc,char*argv[]),在访问argv[1]之前,应该检查argc是否至少为2。
此外,由于要向printf传递一个浮点值(顺便说一句,在传递到printf时,它会转换为双精度),因此应该使用%f格式说明符。%s格式说明符用于字符串(以“\0”结尾的字符数组)。
考虑以下代码片段,
代码段1
int *number = NULL;
*number = 1;
代码段2
int *number = malloc(sizeof(int));
*number = 1;
如果你问这个问题,我假设你知道函数的含义:malloc()和sizeof()。
既然已经解决了,SNIPET 1将引发分段错误。而SNIPET 2则不会。
原因如下。
代码段1的第一行是创建一个变量(*number)来存储其他变量的地址,但在本例中,它被初始化为NULL。另一方面片段二的第二行是创建相同的变量(*number)来存储另一个的地址,在这种情况下,它被赋予了一个内存地址(因为malloc()是C/C++中的一个函数,它返回计算机的内存地址)
关键是你不能把水放在一个没有买过的碗里,或者一个已经买过但没有授权使用的碗里。当您尝试这样做时,计算机会发出警报,并抛出SegFault错误。
您应该只使用接近低级的语言(如C/C++)来面对这些错误。其他高级语言中有一个抽象,可以确保您不会犯此错误。
同样重要的是要理解分段错误不是特定于语言的。
维基百科的Segmentation_fault页面对其进行了很好的描述,只是指出了原因和原因。查看wiki以获得详细描述。
在计算中,分段故障(通常简称为segfault)或访问违规是由具有内存保护的硬件引起的故障,通知操作系统(OS)内存访问违规。
以下是分段故障的一些典型原因:
取消引用NULL指针–这是内存管理硬件的特殊情况试图访问不存在的内存地址(在进程的地址空间之外)试图访问程序无权访问的内存(例如进程上下文中的内核结构)试图写入只读内存(如代码段)
这些通常由导致无效内存访问的编程错误引起:
取消引用或分配给未初始化的指针(指向随机内存地址的通配符指针)取消引用或分配给已释放指针(悬空指针,指向已释放/解除分配/删除的内存)缓冲区溢出。堆栈溢出。试图执行未正确编译的程序。(尽管存在编译时错误,某些编译器仍会输出可执行文件。)
分段错误是由对进程未在其描述符表中列出的页面的请求,或对进程已列出的页面(例如,只读页面上的写入请求)的无效请求引起的。
悬空指针是指可能指向或不指向有效页,但确实指向“意外”内存段的指针。
简单地说:分段故障是操作系统向程序发送信号表示已检测到非法内存访问,并正在提前终止程序以防止防止内存损坏。