什么是分段故障?它在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)
老实说,正如其他海报所提到的那样,维基百科在这方面有一篇很好的文章,所以看看吧。这种类型的错误非常常见,通常称为其他错误,如访问违规或一般保护故障。
它们在C、C++或任何其他允许指针的语言中都没有区别。这些类型的错误通常由以下指针引起:
在正确初始化之前使用在它们指向的内存被重新定位或删除后使用。在索引超出数组边界的索引数组中使用。这通常只在对传统数组或c字符串进行指针计算时发生,而不是基于STL/Boost的集合(在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()时使用错误的格式说明符'
分段错误是由于访问“不属于您的”内存而导致的一种特定错误。它是一种帮助机制,可以防止损坏内存并引入难以调试的内存错误。每当你得到一个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。
“分段错误”表示您试图访问无法访问的内存。
第一个问题是你的论点。main函数应该是int main(int argc,char*argv[]),在访问argv[1]之前,应该检查argc是否至少为2。
此外,由于要向printf传递一个浮点值(顺便说一句,在传递到printf时,它会转换为双精度),因此应该使用%f格式说明符。%s格式说明符用于字符串(以“\0”结尾的字符数组)。