IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言:段错误产生原因及简单的调试方法 -> 正文阅读

[C++知识库]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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:26:01  更:2021-08-06 09:29:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 22:21:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码