Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中,是否可能总是在数组大小的1处生成SEGFULT?_C_Arrays_Segmentation Fault - Fatal编程技术网

在C中,是否可能总是在数组大小的1处生成SEGFULT?

在C中,是否可能总是在数组大小的1处生成SEGFULT?,c,arrays,segmentation-fault,C,Arrays,Segmentation Fault,假设您分配一些数组arr大小n,如下所示: int arr[n]; // Allocated fine printf("%d", arr[n]); // Segfault if possible 是否存在这样一个数字n,我可以始终触发printf行上的segfault?这可能是特定于某些操作系统的 我知道它的未定义行为,我知道当访问它并将其更改为超出范围时,将影响另一个内存区域,这将(可能)在以后给我带来重大问题 我的教授说,它不会总是segfault,我很好奇,在某些情况下,是否有任何方法可

假设您分配一些数组arr大小n,如下所示:

int arr[n]; // Allocated fine
printf("%d", arr[n]); // Segfault if possible
是否存在这样一个数字n,我可以始终触发printf行上的segfault?这可能是特定于某些操作系统的

我知道它的未定义行为,我知道当访问它并将其更改为超出范围时,将影响另一个内存区域,这将(可能)在以后给我带来重大问题

我的教授说,它不会总是segfault,我很好奇,在某些情况下,是否有任何方法可以创建一个大小一定的数组,使用某种类型的操作系统或计算机,每次都能可靠地segfault

这可能吗?我是否可以创建一些条件,导致单个越界访问始终触发segfault


从理论上讲,这是否可能永远是真的?但实际上不会一直发生吗?

不会。越界访问是未定义的行为。UB意味着任何事情都可能发生。在标准系统上,您通常可以找到一种持续导致SEGFULT的方法,但这并不能保证。如果您更改代码中的其他内容,可能会得到二进制移位,从而更改堆栈分配和程序结果

例如,在运行RTEMS 4.9.2的PowerPC 5200(不是很好的MMU)上,以下代码不会创建segfault:

int arr[5];
arr[6] = 10;
int *p = 0;
while (true)
   *(p--) = 666;
事实上,即使这样也不会产生SEGFULT:

int arr[5];
arr[6] = 10;
int *p = 0;
while (true)
   *(p--) = 666;
实际上,未定义的意思是未定义的

要在打印语句中执行此操作,您可以执行以下操作

printf("%d", arr[n]) // Out of bounds access
printf("%f", arr[n]) // wrong type access
但我将再次重申,虽然在特定情况下,这可能会重复出现故障,但决不能保证总是以这种方式发生

要用SIGSEGV可靠地停止POSIX系统,最好的办法是自己提高:

raise(SIGSEGV);
有关强制SIGSEGV信号的更多信息,请参见:

在这里:


否。越界访问是未定义的行为。UB意味着任何事情都可能发生。在标准系统上,您通常可以找到一种持续导致SEGFULT的方法,但这并不能保证。如果您更改代码中的其他内容,可能会得到二进制移位,从而更改堆栈分配和程序结果

例如,在运行RTEMS 4.9.2的PowerPC 5200(不是很好的MMU)上,以下代码不会创建segfault:

int arr[5];
arr[6] = 10;
int *p = 0;
while (true)
   *(p--) = 666;
事实上,即使这样也不会产生SEGFULT:

int arr[5];
arr[6] = 10;
int *p = 0;
while (true)
   *(p--) = 666;
实际上,未定义的意思是未定义的

要在打印语句中执行此操作,您可以执行以下操作

printf("%d", arr[n]) // Out of bounds access
printf("%f", arr[n]) // wrong type access
但我将再次重申,虽然在特定情况下,这可能会重复出现故障,但决不能保证总是以这种方式发生

要用SIGSEGV可靠地停止POSIX系统,最好的办法是自己提高:

raise(SIGSEGV);
有关强制SIGSEGV信号的更多信息,请参见:

在这里:


在一般情况下,正如本所指出的,这是未定义的行为。一般的答案是“永远不要依赖未定义的行为,它的影响永远不会是确定的”

然而,有两种可靠的方法可以在特定的、现代的、普通的系统上实现这一点,这些系统涵盖了现代PC机的大部分,但它不能在所有编译器、体系结构、操作系统等中移植

  • 只需创建一个数组,然后单击。尝试访问元素
    arr[-1]
    ,或将其与另一个极端对齐。不保证,但很可能,因为操作系统不允许您访问受保护的内存,或者如果您正在写入RODATA段,就是这样
  • 在Linux上。在代码覆盖率测试期间,在软件的测试构建中启用此功能是一个好主意:最好在测试阶段崩溃并修复它,然后部署它并使其在生产中崩溃

  • 本指出,在一般情况下,这是一种未定义的行为。一般的答案是“永远不要依赖未定义的行为,它的影响永远不会是确定的”

    然而,有两种可靠的方法可以在特定的、现代的、普通的系统上实现这一点,这些系统涵盖了现代PC机的大部分,但它不能在所有编译器、体系结构、操作系统等中移植

  • 只需创建一个数组,然后单击。尝试访问元素
    arr[-1]
    ,或将其与另一个极端对齐。不保证,但很可能,因为操作系统不允许您访问受保护的内存,或者如果您正在写入RODATA段,就是这样
  • 在Linux上。在代码覆盖率测试期间,在软件的测试构建中启用此功能是一个好主意:最好在测试阶段崩溃并修复它,然后部署它并使其在生产中崩溃

  • 正如其他人所指出的,您无法确保在一般情况下出现分段错误,您可以尝试使用复杂的分配方法,使其在某些系统上更加系统化


    有一种更好的方法可以调试代码并检测此类错误:有一种非常有效的工具可以用来调试代码:
    valgrind
    。检查它是否适用于您的环境。

    正如其他人所指出的那样,您无法确保在一般情况下出现分段错误,您可以尝试使用详细的分配方法,使其在某些系统上更系统化

    有一种更好的方法可以调试代码并检测此类错误:有一种非常有效的工具可以用来调试代码:
    valgrind
    。检查它是否适用于您的环境。

    注意:这使用了来自
    malloc
    的数组,因此从技术上讲,它并不完全相同

    但是,这将在末尾添加一个“保护”页面/区域,这通常会导致SEGFULT

    我经常使用它来调试“逐个”数组索引。我发现它非常有用,我将它作为
    malloc
    包装的一部分添加到了我的生产代码中

    因此,如果目的是想出一些能够调试实际问题的方法,这可能会有所帮助: