常见段错误的原因总结序言的原因总结,段错误归根到底是访问了非法内存。 二、序列越界三、scanf错误使用。 四是指针访问了只读存储器区域。
前言
以前写代码的时候总是发生段错误。 分段故障。 所以,总结常见段落的错误,便于以后查找原因。
原因总结1、段错误的根本原因是访问了不正确的内存。 此内存空间可能不存在、受系统保护、文件不足或文件损坏。 可能的原因如下。
对代码段的访问(通常是由于指针未初始化,指向错误的位置,或取消引用空指针),或对寄存器的访问
示例1 :空指针int * p=取消空引用; printf(%d(n )、*p ); //存储器行地址是代码段,不能访问吗?
例2 )访问register int p=10,包括有不正当价值的内存; printf(%d(n )、*p ); register关键字将变量存储在内核寄存器中,因此无法访问。
野指针:即在定义指针时未初始化,其指向的位置表达式未知的指针。 如果取消对野生指针的引用,则可能会发生段错误或程序崩溃。
防范方案: 1; 定义时初始化为空2; 引用前代入3; 使用后,请记住指向NULL并在每次使用指针时赋值
二、排列越界例如,使用malloc申请了一页内存,使用了却超过了。 跨越数组边界写入数据,在动态分配的内存两端以外写入数据,以及重写堆管理数据结构。 将数据写入动态分配的内存的上一个区域。
(中) p=malloc ) 256; p[-1]=0; p[256]=0; //访问了未知空间的内存
中: int *p=NULL; int a[6]; p=a; for(intI=0; i10; I () p=I; }//堆栈掩蔽检测器访问了未知空间的内存
三、扫码错误使用: int b; 扫描(' % d ',b ); //scanf('%d ',b );
四.指针访问只读存储器区域。 例如char *p=“abcddf”; * p=‘a’; //实际上错误的原因本质上与和解引用空指针类似,“abcddf”在定义时被放置在代码段或常量区域。
//解决方法是将字符串保存在数组中,并将指针指向数组的开头
在此补充程序运行时的内存分配。
1堆栈空间:存储函数运行时发生的临时变量、局部变量、函数条目参数、返回值和const定义的局部变量,函数结束后编译器释放。
2堆:用于存储程序运行时动态分配的内存段,程序员手动申请释放malloc申请,free释放。
3全局区域(静态区域)全局区域用于存储全局变量,主要分为两个分段。 1.bss分段)此分段用于存储未初始化或初始化为0的全局变量和静态变量(static )
2.data段:也称为数据段,在. rodata段中存储初始化不为0的全局和静态变量以及const定义的全局变量
该段在程序结束后由系统释放。
4常量字段:常量字符串放在这里。 程序结束后系统释放
5代码区域:存储函数的代码,也称为. text段。 字符串常数的一部分中也存在代码段
请求内存的三个函数:
1.void * malloc (统一集成); //单位为字节时,申请在200字节的空间中存储int型数据int*p=(int* ) malloc(50*sizeof ) int )
2.void*calloc(unsignedn,unsigned size ); //long *buffer; buffer=(long* ) calloc(20,sizeof ) long ); 得到长整数数组空间
3.void * realloc (void * mem _ address,未指定的int new size ); //重新分配内存
三种方法是申请返回正常(void * )类型的指针,失败并返回NULL; 使用后请务必记住发布free