日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言段错误的有用总结

發布時間:2023/12/31 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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语言段错误的有用总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。