段错误是指程序尝试访问一段不可访问的内存。
在类Unix系统中,当出现段错误时,系统发送信号量SIGSEGV给产生段错误的进程;在Windows系统中,系统会发送异常STATUS_ACCESS_VIOLATION给产生段错误的进程。
产生段错误的原因
程序运行过程中能访问到的内存空间主要有栈和堆。栈存放了函数的本地变量,堆是程序运行过程中能够自由分配和使用的内存空间。产生段错误和栈、堆的访问密切相关。
产生段错误的原因主要有:
- 解引用空指针
- 访问不可访问的内存空间(如内核空间)
- 访问不存在的内存地址
- 试图写一个只读内存空间(如代码段)
- 栈溢出(函数递归调用)
- 使用未初始化的指针(定义时没有初始化或者已经回收)
避免段错误
- 定义指针后初始化
- 数组下标是否越界
- 在堆上分配空间是否足够(内存限制)
- 变量处理时格式控制是否合理
注意事项:
1、出现段错误时,首先应该想到段错误的定义,从它出发考虑引发错误的原因。
2、在使用指针时,定义了指针后记得初始化指针,在使用的时候记得判断是否为NULL。
3、在使用数组时,注意数组是否被初始化,数组下标是否越界,数组元素是否存在等。
4、在访问变量时,注意变量所占地址空间是否已经被程序释放掉。
5、在处理变量时,注意变量的格式控制是否合理等。
段错误产生的原因
1 访问不存在的内存地址
复制代码代码如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = NULL;
*ptr = 0;
}
2 访问系统保护的内存地址
复制代码代码如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = (int *)0;
*ptr = 100;
}
3 访问只读的内存地址
复制代码代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char *ptr = "test";
strcpy(ptr, "TEST");
}
4 栈溢出
复制代码代码如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{
main();
}