欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

C语言段错误的有用总结

发布时间:2023/12/31 64 豆豆
生活随笔 收集整理的这篇文章主要介绍了 C语言段错误的有用总结 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

例题:

有以下两个文件,输出结果是 ()

文件A:

int a[10] = {100};

文件B:

#include <stdio.h>

extern int *a;

void main()

{

    printf("%d", a[0]);

}

A) 100   B) 0   C) 段错误   D) 编译错误

测试结果:

    

解释:

在extern int *a和printf("%d", a[0])这两条语句中,编译器觉得a是一个指针变量,所以它提取存储在那里的指针值,然后对这个结果运行间接訪问操作。但a实际上是整型数组的起始位置,所以作为"指针"获得的这个值实际上是数组的第一个整形元素。其结果解释为一个地址。然后对它进行间接訪问。作为结果,它或者将提取一些随意内存位置的内容。或者因为某种地址错误而导致程序失败。

段错误的常见原因总结:

一、段错误究根到底就是访问了非法内存

这个内存区要么是不存在的,要么 是受到系统保护的,还有可能是缺少文件或者文件损坏。可能的原因包括:

访问代码段(原因经常是指针未初始化指向了错误的位置或解引用空指针)、访问寄存器

例子1:解引用空指针 int *p=NULL; printf("%d\n",*p); //因为内存低地址为代码段,不可访问

例子2:访问含有非法值得内存 register int p =10; printf("%d\n",*p); //由于register关键字使变量存储到内核寄存器中,因此不能访问

野指针:即定义指针时并未对其初始化,其指向的的位置式未知的。对野指针解引用可能造成段错误或者导致程序崩溃

防止方案:1;定义时初始化为NULL 2;解引用前赋值 3;使用完后指向NULL 每次使用指针之前记得赋值就好了

二、数组越界

如:当使用malloc申请了一页内存,但使用却超出了。 越过数组边界写入数据,在动态分配的内存两端之外写入数据,或改写一些堆管 理数据结构(在动态分配的内存之前的区域写入数据)

堆中:p = malloc(256); p[-1] = 0; p[256] = 0; //访问了未知空间的内存

栈中:int *p=NULL; int a[6]; p=a; for(int i=0;i<10;i++){*p++=i;} //stack smashing detected 访问了未知空间的内存

三、scanf错误使用

int b; 

scanf("%d",b);//应为scanf("%d",&b);

四、指针访问只读内存区

如:char *p=“abcddf”; *p=‘A’; //其实本质上错误原因和解引用空指针类似,“abcddf”在被定义时放在了代码段或常量区。

//解决方法是将字符串存到数组中,再将指针指向数组头

这里补充一下程序运行时内存分配:

1 栈区:存放函数运行时产生的临时变量,局部变量、函数的入口参数,返回值和const定义的局部变量,函数结束后由编译器释放。

2 堆区:用于存放程序运行时被动态分配的内存段,一般由程序员手动申请释放malloc申请,free释放。

3 全局区(静态区):全局区用来存储全局变量,主要分为两个段:1. .bss段:该段用于存放未初始化或者初始化为0的全局变量和静态变量(static)

2. .data段:又叫数据段,用于存储初始化不为0的全局变量和静态变量、const定义的全局变量(在.rodata段)

该段在程序结束后由系统释放。

4 常量区:常量字符串就是放在这里的。 程序结束后由系统释放

5 代码区:又叫.text段用于存放函数的代码,部分字符串常量也存在代码段

三个申请内存的函数:

1. void *malloc(unsigned int size); //单位为字节 如要申请200个字节的空间存储int型数据 int *p=(int *)malloc(50 *sizeof(int))

2. void *calloc(unsigned n,unsigned size); //long *buffer; buffer =(long *)calloc(20,sizeof(long)); 获得一块长整型数组空间

3. void *realloc(void *mem_address,unsigned int newsize);//重新分配内存

三种方式,申请成功返回(void *)类型的指针,失败返回NULL;使用完之后切记要free释放

 

总结

以上是生活随笔为你收集整理的C语言段错误的有用总结的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。