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

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

3天内不再提示

什么是段错误?

工程师 来源:聚优致成 作者:聚优致成 2020-09-11 14:04 次阅读

来源:聚优致成

一、什么是段错误?一旦一个程序发生了越界访问,cpu 就会产生相应的保护,于是 segmentation fault 就出现了,通过上面的解释,段错误应该就是访问了不可访问的内存。

这个内存区要么是不存在的,要么是受到系统保护的,还有可能是缺少文件或者文件损坏。

二、段错误产生的原因下面是一些典型的段错误的原因:

非关联化空指针——这是特殊情况由内存管理硬件

试图访问一个不存在的内存地址(在进程的地址空间)

试图访问内存的程序没有权利(如内核结构流程上下文)

试图写入只读存储器(如代码段)

1、访问不存在的内存地址

在C代码,分割错误通常发生由于指针的错误使用,特别是在C动态内存分配。非关联化一个空指针总是导致段错误。

但野指针和悬空指针指向的内存,可能会或可能不会存在,而且可能或不可能是可读的还是可写的,因此会导致瞬态错误。

#include 《stdio.h》int main (void){ int *ptr = NULL; *ptr = 0; return 0;}输出结果:段错误(核心已转储)

现在,非关联化这些变量可能导致段错误:非关联化空指针通常会导致段错误,阅读时从野指针可能导致随机数据但没有段错误,和阅读从悬空指针可能导致有效数据,然后随机数据覆盖。

2、访问系统保护的内存地址

#include 《stdio.h》 int main (void){ int *ptr = (int *)0; *ptr = 100; return 0;}输出结果:段错误(核心已转储)

3、访问只读的内存地址

写入只读存储器提出了一个 segmentation fault,这个发生在程序写入自己的一部分代码段或者是只读的数据段,这些都是由操作系统加载到只读存储器。

#include 《stdio.h》#include 《string.h》 int main (void){ char *ptr = “test”; strcpy (ptr, “TEST”); return 0;}输出结果:段错误(核心已转储)

#include 《stdio.h》 int main (void){ char *ptr = “hello”; *ptr = ‘H’; return 0;}输出结果:段错误(核心已转储)

上述例子ANSI C代码通常会导致段错误和内存保护平台。它试图修改一个字符串文字,这是根据ANSI C标准未定义的行为。大多数编译器在编译时不会抓,而是编译这个可执行代码,将崩溃。

包含这个代码被编译程序时,字符串“hello”位于rodata部分程序的可执行文件的只读部分数据段。

当加载时,操作系统与其他字符串和地方常数只读段的内存中的数据。当执行时,一个变量 ptr 设置为指向字符串的位置,并试图编写一个H字符通过变量进入内存,导致段错误。

编译程序的编译器不检查作业的只读的位置在编译时,和运行类unix操作系统产生以下运行时发生 segmentation fault。

可以纠正这个代码使用一个数组而不是一个字符指针,这个栈上分配内存并初始化字符串的值:

#include 《stdio.h》 int main (void){ char ptr[] = “hello”; ptr[0] = ‘H’; return 0;}

即使不能修改字符串(相反,这在C标准未定义行为,在C char *类型,所以没有隐式转换原始代码,在c++的 const char *类型,因此有一个隐式转换,所以编译器通常会抓住这个特定的错误。

4、空指针废弃

因为是一个很常见的程序错误空指针废弃(读或写在一个空指针,用于C的意思是“没有对象指针”作为一个错误指示器),大多数操作系统内存访问空指针的地址,这样它会导致段错误。

#include 《stdio.h》 int main (void){ int *ptr = NULL; printf (“%d\n”, *ptr); return 0;}输出结果:段错误(核心已转储)

这个示例代码创建了一个空指针,然后试图访问它的值(读值)。在运行时在许多操作系统中,这样做会导致段错误。

非关联化一个空指针,然后分配(写一个值到一个不存在的目标)也通常会导致段错误。

#include 《stdio.h》 int main (void){ int *ptr = NULL; *ptr = 1; return 0;}输出结果:段错误(核心已转储)

下面的代码包含一个空指针,但当编译通常不会导致段错误,值是未使用的。因此,废弃通常会被优化掉,死代码消除。

#include 《stdio.h》 int main (void){ int *ptr = NULL; *ptr; return 0;}

还有,比如malloc 动态分配内存,释放、置空完成后,不可再使用该指针。

#include 《stdio.h》#include 《stdlib.h》#include 《string.h》 int main(){ char* str=(char* )malloc(100); if(*str) { return; } strcpy(str,“hello”); printf(“%s\n”,str); free(str); str=NULL; strcpy(str,“abcdef”); return 0;}输出结果:hello段错误 (核心已转储)

5、堆栈溢出

#include 《stdio.h》#include 《string.h》 int main (void){ main (); return 0;}输出结果:段错误(核心已转储)

上述例子的无限递归,导致的堆栈溢出会导致段错误,但无线递归未必导致堆栈溢出,优化执行的编译器和代码的确切结构。在这种情况下,遥不可及的代码(返回语句)行为是未定义的。

因此,编译器可以消除它,使用尾部调用优化,可能导致没有堆栈使用。其他优化可能包括将递归转换成迭代,给出例子的结构功能永远会导致程序运行,虽然可能不是其他堆栈溢出。

6、内存越界(数组越界,变量类型不一致等)

#include 《stdio.h》int main (void){ char test[10]; printf (“%c\n”, test[100000]); return 0;}输出结果:段错误(核心已转储)

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

    关注

    180

    文章

    7591

    浏览量

    135795
  • 编程
    +关注

    关注

    88

    文章

    3559

    浏览量

    93532
收藏 人收藏

    评论

    相关推荐

    网关错误是什么意思

    网关错误是计算机网络中一个常见且复杂的问题,它通常发生在客户端和服务器之间的通信过程中,导致客户端的请求无法被正确处理或响应。为了全面理解网关错误,本文将从其定义、原因、类型、影响、诊断方法以及解决方案等多个方面进行详细阐述。
    的头像 发表于 09-30 11:40 1032次阅读

    【飞凌嵌入式OK527N-C开发板体验】3.鼠标+硬件编解码+音频播放器

    有偶而的报错,且运行一时间 会有明显卡顿,怀疑是加载一,解码一。 测试音频播放,启动后可以 显示 出播放器画面,但我没鼠标无法播放,但神奇的地方是我这个屏幕有触摸,点按时会导致
    发表于 07-25 23:47

    一文读懂CAN通讯错误

    CAN总线通信技术广泛应用于多个行业,是每个总线设计工程师必学的一个通讯网络。然而,对于CAN通信中的错误帧,许多人仅停留在表面了解,缺乏深入理解,这导致许多工程师在面对总线通信故障时感到无从下手
    的头像 发表于 06-12 08:24 2431次阅读
    一文读懂CAN通讯<b class='flag-5'>错误</b>帧

    使用sophon-demo_v0.1.8_dbb4632_20231116下面的YOLOv8中的yolov8_bmcv历程出现错误的原因?

    使用sophon-demo_v0.1.8_dbb4632_20231116下面的YOLOv8中的yolov8_bmcv历程,出现错误: 定位到代码中出错的函数是 picDec(h, img_file.c_str(), bmimg);这是什么原因呢?这个函数是算能提供的代
    发表于 05-30 07:37

    鸿蒙OpenHarmony:【 hb安装异常处理】

    hb安装过程中出现乱码、错误
    的头像 发表于 04-30 16:28 686次阅读
    鸿蒙OpenHarmony:【 hb安装异常处理】

    一文读懂CAN控制器错误处理的原理

    CAN通讯的错误帧到底是如何被界定的?本文带你轻松了解!错误标定检测到错误条件的站通过发送错误标志指示错误。对于“
    的头像 发表于 04-26 08:25 1475次阅读
    一文读懂CAN控制器<b class='flag-5'>错误</b>处理的原理

    ucosiii的串口打印输出遇到了硬件错误怎么解决?

    我练两天调试了ucos-iii之前是应为一些问题发现系统运行错误,但是到了第二天打开工程从新编译下载程序测试,发现一刚刚开始打印串口消息就出现了硬件错误错误),怀疑是使用了半主机模
    发表于 04-24 06:03

    bm_image转cv::Mat时出现错误的原因?

    bm_image转cv::Mat时出现错误,堆栈信息如下:
    发表于 01-10 07:27

    CMOS设置错误的解决方法

    CMOS设置错误的解决方法  CMOS是计算机中的一块电路,用于存储电脑的基本配置信息。如果设置错误,可能会导致计算机无法正常启动或运行,因此需要尽早解决。本文将为你详细介绍如何解决CMOS设置错误
    的头像 发表于 12-28 15:13 7701次阅读

    ug内部错误,内存访问违例怎么解决

    ug内部错误,内存访问违例怎么解决 内部错误和内存访问违例是编程中常见的问题,它们可能会导致应用程序崩溃、数据丢失或系统不稳定。在本文中,我将详细解释内部错误和内存访问违例的原因,如何解决这些
    的头像 发表于 12-27 16:27 5725次阅读

    初学仿真常见的错误

    本推文针对Sentaurus初学者频繁遇到的错误进行简单整理,具体是包括Sde、Sdevice仿真常见错误
    的头像 发表于 12-03 16:24 1984次阅读
    初学仿真常见的<b class='flag-5'>错误</b>

    vlookup常见的12种错误

    VLOOKUP是Excel中非常常用的函数之一,它能够根据指定的值,在某一列范围内进行查找,并返回相应的值。虽然VLOOKUP是一个强大的函数,但是由于其复杂性和灵活性,常常容易出现一些错误。在本文
    的头像 发表于 12-01 11:19 3020次阅读

    invalid synrax是什么错误

    “invalid synrax” 是英语中的拼写错误,正确的拼法是 “invalid syntax”。语法错误是指程序代码中出现了不符合编程语言规则的语法结构,导致编译器无法理解和编译代码。 语法
    的头像 发表于 11-28 15:59 7768次阅读

    脚本错误scripterror怎么解决

    “脚本错误”(Script Error)通常是在运行或尝试运行一脚本或程序时出现的错误。这种错误可能源于许多不同的原因,包括语法错误、运行
    的头像 发表于 11-26 14:46 7568次阅读

    c语言代码错误怎么找

    当我们编写C语言代码时,常常会遇到一些错误。这些错误可能是语法错误,逻辑错误或者是运行时错误。无论是什么类型的
    的头像 发表于 11-24 10:05 3404次阅读