0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

段错误是什么意思?是何原因引起的?

学益得智能硬件 来源:学益得智能硬件 2023-02-13 09:41 次阅读

刚接触指针的时候,经常会遇到段错误。

root@Turbo:linklist# ls
link.c  link.h  main  main.c
root@Turbo:linklist# ./main
链表初始化成功
Segmentation fault (core dumped)
root@Turbo:linklist#
所谓段错误,就是访问了不能访问的内存。

83c8554a-ab3d-11ed-bfe3-dac502259ad0.png

比如内存不存在,或者受保护等等。 遇到段错误,就得去调试,不管是通过什么手段,一定得先找到哪行代码出现了段错误,然后才能分析修改。

调试段错误的手段很多,对于初学者,我推荐两个,一个是通过打印的方式定位,一个是使用gdb。 打印方法最简单。
root@Turbo:linklist# ls
link.c  link.h  main  main.c
root@Turbo:linklist# ./main
链表初始化成功
Segmentation fault (core dumped)
root@Turbo:linklist#
比如这里有个链表的代码,代码量大概300行,从现象可以看出,链表的初始化成功,紧接着就出现了段错误。 于是我们大概能推测出问题出在了链表的插入操作上。
int insert_link(Node *h, int p, int n)
{
    if (NULL == h)
    {
        return FAILURE;
    }


    //把指针移动到要插入位置的前一个位置
    Node *q = h;
    int k = 1;
    while (k < p)      //q != NULL  防止位置p太大
    {
        q = q->next;
        k++;
    }


    //判断位置是否合法
    if (q == NULL || k > p)    //位置太大  位置太小
    {
        return FAILURE;
    }


    Node *m = (Node *)malloc(sizeof(Node) * 1);
    if (NULL == m)
    {
        return FAILURE;
    }


    m->data = n;
    m->next = q->next;
    q->next = m;


    return SUCCESS;
}
找到链表的插入操作,可以把它分成几个功能,入参判断,移动指针,判断位置是否合法,申请新节点,修改指针域。

在每个功能前面加上一些打印,随便打印什么都行。
int insert_link(Node *h, int p, int n)
{
    //printf("1111
");
    if (NULL == h)
    {
        return FAILURE;
    }


    //printf("2222
");
    //把指针移动到要插入位置的前一个位置
    Node *q = h;
    int k = 1;
    while (k < p)      //q != NULL  防止位置p太大
    {
        q = q->next;
        k++;
    }


    printf("3333
");
    //判断位置是否合法
    if (q == NULL || k > p)    //位置太大  位置太小
    {
        return FAILURE;
    }


    printf("4444
");
    Node *m = (Node *)malloc(sizeof(Node) * 1);
    if (NULL == m)
    {
        return FAILURE;
    }
    printf("5555
");
    m->data = n;
    m->next = q->next;
    q->next = m;


    return SUCCESS;
}
再次运行,程序输出了1和2。
root@Turbo:linklist# gcc main.c link.c -o main
root@Turbo:linklist# ./main
链表初始化成功
1111
2222
Segmentation fault (core dumped)
root@Turbo:linklist#
于是,问题再次被缩小,应该是移动指针的时候出了问题。
//把指针移动到要插入位置的前一个位置
    Node *q = h;
    int k = 1;
    while (k < p)      
    {   
        q = q->next;
        k++;
    }
这几行代码,能跟指针扯上关系的,应该就是第 6 行了。当然,这只是发现了段错误在哪,具体怎么修改,还得根据你的业务逻辑继续分析。

通过打印定位问题确实比较慢。如果代码量比较大,又不能大概判断出问题所在,可以借助一些工具,常用的比如GDB
root@Turbo:linklist# gcc main.c link.c -o main -g
root@Turbo:linklist# gdb main
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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:
.
Find the GDB manual and other documentation resources online at:
    .


For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main...
(gdb) run
Starting program: /root/test/linklist/main 
链表初始化成功
1111
2222


Program received signal SIGSEGV, Segmentation fault.
0x0000555555555783 in insert_link (h=0x5555555592a0, p=5, n=9) at link.c:42
42      q = q->next;
(gdb)
编译的时候加上-g选项,直接使用gdb加上文件名,run启动程序,一眼就能看出错误在第42行。

当然了,这个程序是我故意写的段错误,有些段错误发生在库里面,并不能很直观的看出来在哪一行。这就需要借助断点、单步调试等等操作。

类似GDB的调试工具还有很多,如果是初学者,没必要掌握太多,能解决问题就行。

845e298a-ab3d-11ed-bfe3-dac502259ad0.png  





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • LINUX内核
    +关注

    关注

    1

    文章

    311

    浏览量

    21389
  • GNU
    GNU
    +关注

    关注

    0

    文章

    141

    浏览量

    17333
  • GDB调试
    +关注

    关注

    0

    文章

    23

    浏览量

    1390

原文标题:调试段错误

文章出处:【微信号:学益得智能硬件,微信公众号:学益得智能硬件】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    联想集团突然终止科创板IPO,到底是何原因

    联想集团突然终止科创板IPO,到底是何原因?   10月8日晚,上交所官网显示“联想集团终止科创板上市”,至此联想的IPO之旅仅获受理仅一周就结束。本次IPO备受关注的不仅仅是联想创下史上“最短
    的头像 发表于 10-10 07:47 1.5w次阅读

    9B90的网络LED灯不亮,是何原因

    8M 外部晶体,UART0 完全正常,UART1 工作出错,送出的数据完全不对。UART0 的代码是UART1 的代码拷贝过去修改的。请教可能的原因?另:9B90 的网络LED灯不亮,是何原因
    发表于 08-20 06:21

    何原因导致的STM32的重启

    可以定位是硬件问题了,但是我左看右看也看不出硬件哪里出了问题;本来想放弃,想想这个问题不搞明白,后患无穷;采用的是仿真的手段,看看是何原因导致的重启:程序中加入对RCC_CSR寄存器清零的代码,以便在程序...
    发表于 08-02 08:54

    何原因导致的STM32程序仿真重启

    何原因导致的STM32程序仿真重启?怎样去解决这个问题?
    发表于 09-24 06:27

    Labview运行myrio冲突拒绝访问是何原因导致的

    Labview运行myrio冲突拒绝访问是何原因导致的?怎样去解决Labview运行myrio冲突拒绝访问的问题呢?
    发表于 02-23 06:52

    请教大神树莓派pico项目创建后,rtthread文件夹没有文件是何原因

    请教大神树莓派pico项目创建后,rtthread文件夹没有文件是何原因
    发表于 09-28 09:56

    Firefly-RK3288摄像头模组打开发生错误何原因

    我使用的是OV8858摄像头模组,无论是使用自带的照相机应用还是从网上下载的360摄像机应用,第一次打开摄像头均使用正常,关闭后第二次再打开,就显示摄像头发生错误,是何原因
    发表于 10-08 16:12

    为什么我不能下载spc5studio呢?是何原因

    为什么我不能下载spc5studio?是何原因
    发表于 01-17 06:18

    Proteus单片机仿真输出无高电平是何原因

    Proteus单片机仿真输出无高电平是何原因
    发表于 04-23 16:39

    proteus中cpu负载过大无法仿真是何原因?怎么解决?

    proteus中cpu负载过大无法仿真是何原因?怎么解决?
    发表于 04-23 16:40

    modbus通讯延迟回复导致读取错位是何原因

    modbus通讯延迟回复导致读取错位是何原因
    发表于 05-05 16:09

    导致致命异常错误和无效页错误原因是什么?

    导致致命异常错误和无效页错误原因是什么? 如果Microsoft Word或Excel“崩溃”,意味着在程序执行过程中出现了严重的错误。操作系统常常会发现存在一个严重问题,并
    发表于 08-05 10:33 950次阅读

    硬件设计中的30个错误想法和原因分析

    硬件设计中的30个错误想法和原因分析
    发表于 12-15 18:25 97次下载

    何原因造成芯片产业烂尾潮?

    在短短一年多时间里,分布于我国江苏、四川、湖北、贵州、陕西等5省的6个百亿级半导体大项目先后停摆。业界担忧,造芯热引发烂尾潮,造成国有资产损失,延误芯片产业发展大好机遇。那么问题来了,是何原因造成上述烂尾潮?中国芯崛起之路又当如何前行?
    的头像 发表于 11-03 09:12 1.3w次阅读

    半桥谐振LLC效率偏低是何原因?资料下载

    电子发烧友网为你提供半桥谐振LLC效率偏低是何原因?资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
    发表于 04-05 08:45 22次下载
    半桥谐振LLC效率偏低是<b class='flag-5'>何原因</b>?资料下载