段错误如何调试

news2024/11/24 13:21:38

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 段错误产生的原因
  • 问题1:访问不存在的内存地址
  • 问题2:访问只读的内存地址
  • 问题3:栈溢出
  • 问题4:内存越界
  • 如何解决段错误
    • 方法一:使用C语言printf函数打印来判断出错位置
      • 有可能会出现的问题:打印不出来信息。如下方实例
      • 解决问题的方法
      • 为什么可以这样解决
    • 方法二:借助linux当中的gdb来调试
  • 总结


前言

嵌入式C开发,或多或少都遇到段错误(segmentation fault )。段错误(Segmentation fault)是一种运行时错误,在程序运行时可能由于某些原因而发生。下面是我对一些典型的段错误总结。


提示:以下是本篇文章正文内容,下面案例可供参考

段错误产生的原因

1、访问不存在的内存地址
2、访问只读的内存地址
3、栈溢出
4、内存越界

注意: 这里我总结了在大学期间遇到的问题,有可能段错误产生的原因不止这些。

问题1:访问不存在的内存地址

#include <stdio.h>
 
int main(int argc, char **argv)
{
    printf("==================段错误==================\n");
 
    int *p = NULL;
    *p = 2244;
 
    return 0;
}

在这里插入图片描述

问题2:访问只读的内存地址

#include "stdio.h"
#include <stdlib.h>
#include "string.h"
void main()
{
	printf("=================段错误==================\n");
	char Data[] = "123456";
	char *data = NULL;	//即使初始化为空,指针data可能是指向了一个只读的内存:memcpy执行失败,造成空指针解引用(空指针间接引用)
	memcpy (data,Data,sizeof(Data));	//引用空指针
	printf ("data is %s.\nand sizeof(Data) is %d.\n", data, sizeof(Data));
	free(data);
	data = NULL;
}
#include <stdio.h>
 
int main(int argc, char **argv)
{
    printf("==================段错误==================\n");
 
    char *str = "hello world";
    str[0] = 'H';
 
    return 0;
}

在这里插入图片描述

问题3:栈溢出

    程序的有效内存还可以再分为多个区域,每个区域都有不同的作用,比如代码区、全局数据区、堆区、栈区、动态链接库区等。栈就是这些内存分区中的一个。栈的作用就是存储程序的局部数据

    对于C/C++来说,局部数据是指在函数内部定义的数据。例如在函数内部定义的变量、指针、参数、结构体、数组、对象、引用等,它们都要保存到栈中。

    那么,栈为什么会溢出?

    对每个程序来说,栈能使用的内存是有限的,一般是 1M~8M,这在编译时就已经决定了,程序运行期间不能再改变。如果程序使用的栈内存超出最大值,就会发生栈溢出(Stack Overflow)错误,程序就崩溃了。

    最常见的栈溢出现象就是递归。每次递归就相当于调用一个函数,函数每次被调用时都会将局部数据(在函数内部定义的变量、参数、数组、对象等)放入栈中。

    如果递归1000次,那么就会将1000份这样的数据放入栈中。这些数据占用的内存直到整个递归结束才会被释放,在递归过程中只会累加,不会释放。如果递归次数过多,并且局部数据也多,那么会使用大量的栈内存,很容易就导致栈溢出了。

#include <stdio.h>
 
static void test(void)
{
    char buf[2048 * 2048] = {0};    //每次递归均会分配存储区
    static int i = 0;
    i++;
    printf("i = %d\n", i);
    test();    //递归
}
 
int main(int argc, char **argv)
{
    printf("==================段错误==================\n");
 
    test();
 
    return 0;
}

在这里插入图片描述

问题4:内存越界

#include <stdio.h>
 
int main(int argc, char **argv)
{
    printf("==================段错误==================\n");
 
    static char arr[8] = {0, 1, 2, 3, 4, 5, 6, 7};
 
    printf("arr[4444] = %d\n", arr[4444]);    //访问下标超出了数组长度
 
    return 0;
}

在这里插入图片描述

如何解决段错误

方法一:使用C语言printf函数打印来判断出错位置

有可能会出现的问题:打印不出来信息。如下方实例

#include <stdio.h>

int main ()
{
    //指针没有初始化,因为野指针写了100,这个代码肯定就会出现段错误问题
	printf("11111");
	int *p;
	printf("2222");
	*p = 100;
	printf("33333");
	return 0;
}

上图的c语言程序,运行结果如下:
在这里插入图片描述
出现的问题:无法正常打印

解决问题的方法

解决的方法是要在每个printf函数输出完内容后面加上\n

#include <stdio.h>

int main ()
{
    //指针没有初始化,因为野指针写了100,这个代码肯定就会出现段错误问题
	printf("11111\n");
	int *p;
	printf("2222\n");
	*p = 100;
	printf("33333\n");
	return 0;
}

修改后的C语言程序运行结果如下图:
在这里插入图片描述

为什么可以这样解决

    C语言的\n有两个作用。第一个:起到换行作用。第二个:起到刷新缓冲区的作用。这里问题的解决,就是使用了其第二个作用。因此,在日常写程序的时候,使用printf函数的时候加上\n会更加稳妥一些
    不然,出现一些玄学问题,肯定又得多掉一些头发了。

方法二:借助linux当中的gdb来调试

第一步:后面加上 -g
在这里插入图片描述
第二步:使用gdb来运行test文件
在这里插入图片描述

最后:输入run+回车
在这里插入图片描述
现在,我们就可以观察到段错误出现在哪里了。
注意:有可能自己下载虚拟机上面没有gdb,那么需要先安装,然后再使用。

总结

遇到错误大家一定不要慌,不着急慢慢来。多找找资料,就能把问题都解决掉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1167923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海康监控摄像机和录像机接入LiveMedia GB28181平台实现远程调取监控视频

海康威视各种型号监控摄像头或硬盘录像机&#xff08;NVR/HVR&#xff09;接入LiveMedia GB28181平台配置过程都非常简单明了&#xff0c;但有些细节需要注意&#xff0c;避免走弯路。 1、基本要求 (1) 网络要求 总体来说&#xff0c;只要监控设备和GB28181平台的网络是连通…

RT-DETR 项目【训练】【验证】【推理】脚本

文章目录 训练 --train.py推理 --detect.py验证 --val.py不训练,只查看模型结构/参数量 --test.py有同学问 RT-DETR 怎么训练,其实和 YOLOv8 几乎一样,但是有很多同学没接触过 v8 我这里直接给大家写好几个脚本,大家直接在我的脚本上调节参数就可以训练了, 脚本包含【训…

使用Gorm进行CRUD操作指南

使用GORM在Go中创建、读取、更新和删除记录的逐步教程 在数据库管理中&#xff0c;CRUD操作是应用程序的支柱&#xff0c;它们使数据的创建、检索、更新和删除成为可能。强大的Go对象关系映射库GORM通过抽象SQL语句的复杂性&#xff0c;使这些操作变得轻松。本文将作为您全面指…

内网穿透Windows下快速搭建个人WEB项目无需服务器

&#x1f4d1;前言 本文主要是windows下内网穿透文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力…

实测用AI还原让子弹飞名场面

最近这两天&#xff0c;郭德纲说英语相声的视频刷到了一遍又一遍&#xff0c;这些视频并非简单的配音或者AI变声&#xff0c;而是高度贴合人物声线和风格、甚至连嘴型都匹配&#xff0c;如果不仔细看&#xff0c;你根本看不出任何破绽&#xff0c;因为内容是郭德纲的&#xff0…

Linux查看磁盘、内存、cpu信息

1. 查看磁盘空间信息&#xff1a;lsblk 2. 查看内存信息&#xff1a;awk $3"kB"{$2$2/1024^2;$3"GB";} 1 /proc/meminfo | column -t 3. 查看cup相关信息&#xff1a;lscup

解决ModuleNotFoundError: No module named ‘yaml‘

报错&#xff1a;ModuleNotFoundError: No module named yaml 使用&#xff1a; pip install yaml 仍然报错&#xff1a; 最终解决方案&#xff1a; pip install pyyaml 或者 conda install pyyaml

【Redis】数据类型前置知识

文章目录 前置知识redis的单线程架构 前置知识 type命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列表&#xff09;、hash&#xff08;哈希&#xff09;、set&#xff08;集合&#xff0…

各位社区工作者!打工而已,不要太上头!!

社工家人们&#xff0c;打工而已&#xff0c;不要太上头&#xff01;咱能偷懒的就偷懒啊&#xff01; 合情合理的偷懒不仅让你更轻松&#xff0c;工作效率还会提高&#xff0c;何乐而不为呢&#xff01;&#xff01;就比如说各种报告啊&#xff0c;活动方案这些啊&#xff0c;…

Latex编辑记录

1 第一段默认是不首行缩进的 在最前面合适的地方&#xff0c;也即是有usepackage类似定义的地方粘贴下列语句 \usepackage{indentfirst} 然后在要首行缩进的地方&#xff0c;放下面这个语句即可 \setlength{\parindent}{2em} 2 公式编辑 3 对文本高亮标记 \usepackage{soul}…

【前端设计】HTML+CSS+JavaScript基本特性

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

阿里云上传

/*** 上传图片** param file 文件* return* throws Exception*/ PostMapping(value "/aliUpload") ResponseBody public AjaxResult aliUpload(MultipartFile file){//获取文件后缀String extension FileUploadUtils.getExtension(file);String imgFormat "{…

虹科分享 | AR眼镜开启工业创新之旅!

文章来源&#xff1a;虹科数字化与AR 阅读原文&#xff1a;https://mp.weixin.qq.com/s/3qBr44ZYWpNaU8xPBBlEYA AR眼镜&#xff0c;开启无限创新之旅&#xff01; 智能AR眼镜被视为在工业应用中带来最大益处的智能设备之一。它不仅能够解放双手&#xff0c;提高工作效率&…

解决Visual Studio Code 控制台中文乱码问题

C和CPP运行编码指定 "code-runner.executorMap": {"c": "cd $dir && gcc -fexec-charsetGBK $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt","cpp": "cd $dir && g -fexec-charsetGBK $…

【Mysql系列】从零开始学MySQL:Docker部署快速上手

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【代码学习】voxel 或者 pillar,稀疏张量 转 稠密张量 的代码理解,理解了很久

需要 feature 和 对应 的坐标 coords debug&#xff1a;转置&#xff0c;不然维度不匹配&#xff01; 对应的代码&#xff0c;向量化 应该 比 for循环快 def voxel_indexing(self, sparse_features, coords): # sparse_features: [N, C], coords:[N, 4]dim sparse_features.…

前端学习之webpack的使用

概述 webpack是一个流行的前端项目构建工具&#xff08;打包工具&#xff09;&#xff0c;可以解决当前web开发中所面临的问题。 webpack提供了友好的模块化支持&#xff0c;以及代码压缩混淆、处理js兼容问题、性能优化等强大的功能&#xff0c;从而让程序员把工作重心放到具…

华为是怎么做全面预算管理的?

大家好&#xff0c;我是老原。 在之前的文章分享中&#xff0c;都穿插着一个很重要但是不被你们重视的的部分&#xff0c;就是预算管理这块。 有很多新手项目经理在做计划的时候&#xff0c;发现自己设备和步骤都不熟悉&#xff0c;根本无从下手&#xff0c;不知道怎么做。 …

大模型 其他方案的进度

Llama2 1、中文提问&#xff0c;英文的回答&#xff0c;对于中文不友好 2、网上还没有看到很详细的微调教程 3、虽然Llama2的预训练数据相对于第一代LLaMA扩大了一倍&#xff0c;但是中文预训练数据的比例依然非常少&#xff0c;仅占0.13%&#xff0c;这也导致了原始Llama2的中…

启用 EGO 的 LSF

启用 EGO 的 LSF 具有 LSF 的企业网格协调器&#xff08;enterprise grid orchestrator EGO&#xff09;能够提供系统基础结构&#xff0c;来控制和管理集群资源。 资源是应用程序使用的物理和逻辑实体。 LSF 资源按照 EGO资源分配计划中的定义进行共享。 一、EGO 组件概览 …