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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

C语言:段错误产生原因及简单的调试方法

發布時間:2023/12/31 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言:段错误产生原因及简单的调试方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

段錯誤產生原因

1.訪問不存在的內存地址

如下面代碼,ptr沒有申請空間就直接拷貝數據:

#include?<stdio.h> #include?<string.h> #include?<stdlib.h>int?main(int?argc,?char?*argv[]) {char?*ptr?=?NULL;//This is the wrong implementation:strncpy(ptr,?"abc",?3);//ptr沒有申請空間就直接使用//The?right?way://ptr?=?(char?*)malloc(sizeof(char)?*?10);//memset(ptr,?0,?10);//strncpy(ptr,?"abc",?3);return?0; }

2.訪問只讀的內存地址

錯誤做法:往字符串常量空間拷貝新的數據

#include?<stdlib.h> #include?<stdio.h> #include?<string.h>int?main(int?argc,?char?*argv[]) {char?*ptr?=?"test";strcpy(ptr,?"TEST1");return?0; }

3.訪問系統保護的內存地址

如:

#include?<stdio.h>int?main(int?argc,?char?*argv[]) {int?*ptr?=?(int?*)0;*ptr?=?100;return?0; }

4.棧溢出

如:

#include?<stdlib.h> #include?<stdio.h> #include?<string.h>int?main(int?argc,?char?*argv[]) {main(argc,?argv); }

初學時兩種常用的段錯誤調試方法

1.使用printf輸出調試信息

這個是看似最簡單但往往很多情況下是十分有效的調試方式,也許可以說是程序員用的最多的調試方式。簡單來說,就是在程序的重要代碼附近加上printf輸出信息,這樣可以跟蹤并打印出段錯誤在代碼中最可能出現的位置。

使用案例:

以下面這段錯誤代碼為例:

#include?<stdio.h> #include?<string.h> #include?<stdlib.h>int?main(int?argc,?char?*argv[]) {char?*ptr?=?NULL;//This is the wrong implementation:strncpy(ptr,?"abc",?3);//ptr沒有申請空間就直接使用return?0; }

可以在代碼中添加printf調試信息:

#include?<stdio.h> #include?<string.h> #include?<stdlib.h>int?main(int?argc,?char?*argv[]) {printf("line:%d\n",?__LINE__);?//單純打印代碼行數char?*ptr?=?NULL;//This is the wrong implementation:printf("line:%d\n",?__LINE__);?//單純打印代碼行數strncpy(ptr,?"abc",?3);//ptr沒有申請空間就直接使用printf("line:%d\n",?__LINE__);?//單純打印代碼行數return?0; }

編譯運行后,會有如下輸出:

line:7 line:10 Segmentation?fault?(core?dumped)

通過日志信息,就可以看到strncpy(ptr, "abc", 3);語句沒有被執行,我們就可以根據定位到的位置來排除ptr是否是未分配空間或者分配的空間不足引發的問題

2.使用gcc和gdb

調試步驟:

1、為了能夠使用gdb調試程序,在編譯階段加上-g參數,還是以下面這段錯誤代碼為例:

#include?<stdio.h> #include?<string.h> #include?<stdlib.h>int?main(int?argc,?char?*argv[]) {char?*ptr?=?NULL;//This is the wrong implementation:strncpy(ptr,?"abc",?3);//ptr沒有申請空間就直接使用return?0; }

編譯代碼添加-g選項

gcc?-g?-o?test?test.c

編譯出test程序,然后用gdb調試:

linux@linux:~/test$?gdb?./test GNU?gdb?(Ubuntu?8.1-0ubuntu3)?8.1.0.20180409-git Copyright?(C)?2018?Free?Software?Foundation,?Inc. License?GPLv3+:?GNU?GPL?version?3?or?later?<http://gnu.org/licenses/gpl.html> This?is?free?software:?you?are?free?to?change?and?redistribute?it. There?is?NO?WARRANTY,?to?the?extent?permitted?by?law.??Type?"show?copying" and?"show?warranty"?for?details. This?GDB?was?configured?as?"x86_64-linux-gnu". Type?"show?configuration"?for?configuration?details. For?bug?reporting?instructions,?please?see: <http://www.gnu.org/software/gdb/bugs/>. Find?the?GDB?manual?and?other?documentation?resources?online?at: <http://www.gnu.org/software/gdb/documentation/>. For?help,?type?"help". Type?"apropos?word"?to?search?for?commands?related?to?"word"... Reading?symbols?from?./test...done. (gdb)?r Starting?program:?/home/linux/test/test?Program?received?signal?SIGSEGV,?Segmentation?fault. 0x0000555555554611?in?main?(argc=1,?argv=0x7fffffffe528)?at?test.c:9 9???????????????????????????????strncpy(ptr,?"abc",?3);//ptr沒有申請空間就直接使用 (gdb)?quit A?debugging?session?is?active.Inferior?1?[process?15829]?will?be?killed.Quit?anyway??(y?or?n)?y

從輸出看出,程序到SIGSEGV信號,觸發段錯誤,并提示地址0x0000555555554611以及代碼第9行出錯。

當然,還有利用core文件和gdb配置配合調試、使用objdump以及catchsegv命令的其他更為復雜的調試手段,這里就不展開講。

總結

以上是生活随笔為你收集整理的C语言:段错误产生原因及简单的调试方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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