c语言打开文件出现分段故障,分割故障的常见原因的确定列表

24d5adacc4d5bc78d55513c999accfd0.png

肥皂起泡泡

警告!以下是电势分割错误的原因。几乎不可能列出所有的理由。..此列表的目的是帮助诊断现有的分段故障。分割错误与未定义行为的关系不可能压力够大了!以下所有可能造成分段错误的情况在技术上都是未定义的行为。这意味着他们可以什么都行,不只是赛段错误-就像有人在Usenet上说的那样,“编译器让恶魔飞出你的鼻子是合法的。“.当您有未定义的行为时,不要指望发生分段错误。您应该了解C和/或C+中存在哪些未定义的行为,并避免编写包含它们的代码!关于未定义行为的更多信息:用C语言生成分段错误的最简单的标准是什么?未定义、未指定和实现定义的行为未定义的行为是如何定义的?什么是分段故障?简而言之,当代码试图访问它的内存时,会导致分段错误。没有访问权限..每个程序都有一块内存(RAM)可以使用,出于安全考虑,它只能访问该块中的内存。关于什么是分段错误的更详细的技术解释是,见什么是分割错误?.以下是分割错误的最常见原因。再一次,这些应该用于诊断现有的分段故障。..要学会如何避开它们,学习你的语言未定义行为.这个列表也是无法替代您自己的调试工作。..(请参阅答案底部的那一节。)这些都是您可以查找的东西,但是调试工具是解决问题的唯一可靠方法。访问空指针或未初始化指针如果有一个指针为NULL(ptr=0)或完全未初始化(尚未设置为任何内容),试图使用该指针访问或修改具有未定义的行为。int* ptr = 0;*ptr += 5;因为分配失败(如malloc或new)将返回一个空指针,在使用它之前,应该始终检查指针是否为空。还请注意,甚至读未初始化指针(以及一般的变量)的值(不取消引用)是未定义的行为。有时,这种对未定义指针的访问可能非常微妙,例如试图将此类指针解释为C print语句中的字符串。char* ptr;sprintf(id, "%s", ptr);另见:如何检测C中变量是否未初始化/捕获分段故障串和int的串联导致SEG故障C访问悬空指针如果你用malloc或new分配内存,然后再分配free或delete通过指针的内存,这个指针现在被认为是一个悬吊指针..销毁它(以及简单地读它的值-如果您没有给它分配一些新值(例如NULL)-是未定义的行为,并且可能导致分段错误。Something* ptr = new Something(123, 456);delete ptr;std::cout <foo <

   return stupidFunction(n);}堆栈溢出的另一个原因是一次有太多(非动态分配)变量。int stupidArray[600851475143];在野外出现堆栈溢出的一种情况是简单地忽略了return语句中用于防止函数中无限递归的条件中的语句。那个故事的寓意,始终确保您的错误检查工作!另见:在C中创建大数组时分割故障初始化数组时SEG故障野生指针创建一个指向内存中某个随机位置的指针就像用代码玩俄罗斯轮盘赌一样-你很容易错过并创建一个指向你没有访问权限的位置的指针。int n = 123;int* ptr = (&n + 0xDEADBEEF); //This is just stupid, people.一般情况下,不要创建指向文字内存位置的指针。即使他们一次工作,下一次他们可能不会工作。您无法预测程序的内存在任何给定执行时的位置。另见:“野生指针”在C中的含义是什么?试图在数组结束后读取数组是一个连续的内存区域,每个连续元素位于内存中的下一个地址。然而,大多数数组对于它们有多大,或者最后一个元素是什么,并没有一种与生俱来的感觉。因此,很容易吹过数组的末尾,并且永远不知道它,特别是当您使用指针算法时。如果在数组结束后读取,则可能会进入未初始化或属于其他内容的内存。这是技术上的未定义行为..分段故障只是许多潜在的未定义行为之一。[坦白地说,如果你在这里有段错的话,你就很幸运了。另一些则更难诊断。// like most UB, this code is a total crapshoot.int arr[3] {5, 151, 478};int i = 0;while(arr[i] != 16){

   std::cout <

   i++;}或者经常看到的for带着<=而不是

   std::cout <

   std::cout <

   i++;}对于C-字符串,它确实是偶然的\0会有什么不同。您应该假设它会避免未定义的行为:所以最好编写char str[4] = {'f', 'o', 'o', '\0'};试图修改字符串文本如果将字符串文本赋值给char*,则不能对其进行修改。例如.。char* foo = "Hello, world!"foo[7] = 'W';.触发器未定义行为,分割错误是一个可能的结果。另见:为什么这个字符串反转C代码会导致分段错误?不匹配分配与去分配方法你必须用malloc和free一起,new和delete一起,和new[]和delete[]在一起。如果你把它们混为一谈,你可能会有段错和其他奇怪的行为。另见:C+中删除malloc的行为删除指针时的分段错误(内核转储)工具链中的错误。编译器的机器代码后端中的错误非常能够将有效的代码转换为分段错误的可执行文件。链接器中的一个bug肯定也能做到这一点。特别可怕的是,这不是由您自己的代码调用的UB。尽管如此,你应该一直认为问题是你自己,直到事实证明并非如此。其他原因分割错误的可能原因与未定义行为的数量一样多,甚至标准文档也无法列出。一些较不常见的原因需要检查:由于其他UB而在某些平台上生成的UD2C+STL映射:操作符[]在被删除的条目上完成调试调试工具有助于诊断分段故障的原因。使用调试标志编译程序(-g),然后使用调试器运行它,以查找分段错误可能发生的位置。最近的编译器支持用-fsanitize=address,这通常会导致程序运行速度慢2倍,但能够更准确地检测地址错误。但是,该方法不支持其他错误(如从未初始化内存读取或泄漏非内存资源(如文件描述符),因此不可能使用许多调试工具和阿桑同时。内存调试器GDB/Mac,Linuxval差制(Memcheck)\linux记忆博士Windows此外,建议使用静态分析工具来检测未定义的行为-但同样,它们只是帮助您查找未定义行为的工具,而且它们不能保证查找所有未定义行为的出现。但是,如果您真的不走运,那么使用调试器(或者更少使用调试信息重新编译)可能会对程序的代码和内存产生足够的影响,使分段错误不再发生,这种现象称为海星虫.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值