当前位置:  开发笔记 > 编程语言 > 正文

segfault在什么时候发生?

如何解决《segfault在什么时候发生?》经验,为你挑选了3个好方法。

以下代码是否在数组[10] = 22或数组[9999] = 22处进行了?
我只想弄清楚整个代码是否会在它出错之前执行.(用C语言编写).

#include 
int main(){

int array[10];
int i;
for(i=0; i<9999; ++i){
    array[i] = 22;
}    
return 0;    
}

Daniel Wedlu.. 13

这取决于...如果阵列后的记忆[9]是干净的,然后没有什么可能发生,直到ofcourse一个达到其被占用的内存段.

试试代码并添加:

 printf("%d\n",i);

在循环中你会看到它崩溃和烧伤的时候.我得到了各种结果,范围从596到2380.



1> Daniel Wedlu..:

这取决于...如果阵列后的记忆[9]是干净的,然后没有什么可能发生,直到ofcourse一个达到其被占用的内存段.

试试代码并添加:

 printf("%d\n",i);

在循环中你会看到它崩溃和烧伤的时候.我得到了各种结果,范围从596到2380.


是的,你可能会很幸运.要真正了解正在发生的事情,您应该在调试器中单步执行反汇编并注意segfault.这将是一项有价值的练习.
打印到stderr,因为stdout被缓冲,你可能根本看不到任何输出,并且缓冲区没有刷新信号.
SIGSEGV是触摸未映射到进程地址空间的页面的结果.在堆栈溢出的情况下,它取决于堆栈的大小以及堆栈的增长方式.对于堆分配,您的进程获取的内容始终是页面大小的倍数.一个页面可以分解为许多分配.SIGSEGV在您离开页面末尾并且未映射下一个虚拟地址时不会触发,并且不会出现故障.请参阅我的回答以获取更多信息.NicDumZ,使用printf()进行调试没有错.在某些情况下,它甚至可以是更好的选择之一.

2> Nicolas Duma..:

使用调试器?

$ gcc -g seg.c -o so_segfault
$ gdb so_segfault
GNU gdb 6.8-debian
Copyright (C) 2008 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 "i486-linux-gnu"...
(gdb) run
Starting program: /.../so_segfault 
Program received signal SIGSEGV, Segmentation fault.
0x080483b1 in main () at seg.c:7
7       array[i] = 22;
(gdb) print i
$1 = 2406
(gdb) 

实际上,如果再次运行它,您将看到对于相同的i值,并不总是会发生段错误.可以肯定的是,当i> = 10时会发生这种情况,但是没有办法确定它将崩溃的i的值,因为这不是确定性的:它取决于内存的分配方式.如果内存是空闲的,直到数组[222](也就是没有其他程序使用它),它将一直持续到i = 222,但是对于i> = 10的任何其他值,它也可能崩溃.



3> jalf..:

答案可能是.C语言没有说明在这种情况下会发生什么.这是未定义的行为.编译器不需要检测问题,做任何事情来处理问题,终止程序或其他任何东西.所以它什么也没做.

你写的不是你的记忆,在实践中可能会发生以下三种情况之一:

你可能很幸运,只是得到一个段错误.如果您点击未分配给您的流程的地址,则会发生这种情况.操作系统会检测到这一点,并向您抛出错误.

你可能会击中记忆那是真正的未使用的,在这种情况下,不会发生错误的时候了.但是,如果内存被分配并在以后使用,它将覆盖您的数据,如果您希望它仍然存在,那么您将获得一些不错的延迟操作错误.

您可能会点击实际用于其他内容的数据.你需要覆盖它,有时很快,当需要原始数据时,它会读取你的数据,然后会出现不可预测的错误.

写出界限:就是不要这样做.C语言在发生时不会告诉你什么,所以你必须自己关注它.


当你遇到段错误时,说你很幸运的+1.如果您在阵列外部访问并且没有得到段错误,则很难找到错误.
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有