Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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++ 带阵列的分段故障_C++_C_Arrays_Segmentation Fault - Fatal编程技术网

C++ 带阵列的分段故障

C++ 带阵列的分段故障,c++,c,arrays,segmentation-fault,C++,C,Arrays,Segmentation Fault,关于阵列,我有两个问题: 第一个是关于以下代码: int a[30]; //1 a[40]=1; //2 为什么第2行没有给出SEGFULT,它应该给出,因为已经分配了数组 只有30 int空间和分配空间之外的任何解引用都应给出segfault 第二:假设上述代码有效,那么[40]有没有可能被重写,因为它不是arrray的保留范围 提前感谢。这是未定义的行为-它可能会崩溃,可能会无声地损坏数据,可能不会产生可观察的结果,等等。不要这样做 在您的示例中,可能的解释是,数组是堆栈分配的,因此

关于阵列,我有两个问题:

第一个是关于以下代码:

int a[30];  //1
a[40]=1;   //2
为什么第2行没有给出SEGFULT,它应该给出,因为已经分配了数组 只有30 int空间和分配空间之外的任何解引用都应给出segfault

第二:假设上述代码有效,那么[40]有没有可能被重写,因为它不是arrray的保留范围


提前感谢。

这是未定义的行为-它可能会崩溃,可能会无声地损坏数据,可能不会产生可观察的结果,等等。不要这样做


在您的示例中,可能的解释是,数组是堆栈分配的,因此数组周围有大量可供写入的地址,因此没有立即观察到的结果。但是,根据堆栈在系统上的增长方式(向大地址还是向小地址)的不同,这可能会覆盖调用堆栈上函数的返回地址和临时地址,这将使程序崩溃,或者在尝试从函数返回时使其行为失范。

出于性能原因,C不会在每次访问时检查数组大小。您还可以通过直接指针访问元素,在这种情况下,无法验证访问。 只有在分配给进程的内存不足时,SEGFULT才会发生


对于第二个问题,是的,它可以被覆盖,因为该内存分配给您的进程,并且可能被其他变量使用。

这取决于系统在何处分配了该数组,如果由于偶然性,位置40位于操作系统保留内存中,则您将收到SEGFULT。

是的,它最终将被覆盖

如果你
malloc
space,你应该会得到一个segfault(或者至少我认为是这样),但是当使用一个数组而不分配空间时,你可以在一段时间内覆盖内存。它最终会崩溃,可能是当程序执行数组大小检查时,也可能是当您点击为其他内容保留的内存块时(不确定引擎盖下发生了什么)


有趣的是,IIRC,efence也无法捕捉到这一点:D.

只有在您对系统的其余部分执行非法操作时,您的应用程序才会崩溃:如果您尝试访问一个您的程序不拥有的虚拟内存地址,所发生的情况是您的硬件会注意到,并会通知您的操作系统,它会因为一个分段错误而终止应用程序:您访问了一个不应该访问的内存段

但是,如果您访问一个随机内存地址(这就是您所做的:肯定
a[40]
在数组
a
之外,但它可能在任何地方),您就可以访问一个有效的内存单元(这就是发生在您身上的情况)

这是一个错误:您可能会覆盖程序拥有的某些内存区域,从而有可能在其他地方破坏程序,但系统无法知道您是有意还是无意访问它,并且不会杀死您


用托管语言编写的程序(即:在受保护的环境中运行的程序检查任何内容)会注意到错误的内存访问,但C不是托管语言:您可以自由地做任何您想做的事情(只要不给系统的其余部分造成问题).

第2行工作且不抛出segfault的原因是,在C/C++中,数组是指针。因此,数组变量a指向某个内存地址,例如1004。数组语法告诉您的程序从数组的位置向下查找数组元素的字节数

这意味着

printf("%p", a);
// prints out "1004"

应该打印相同的值

但是,

printf("%p", a[40]);
// prints out "1164"

返回的内存地址比a的地址低sizeof(int)*40。

标记为C,没有多少语言会默默地接受它。它甚至可能让你的女朋友怀孕,不管你有没有怀孕!即使使用malloc,也可能不会出现segfault,这取决于操作系统和进程完成的其他内存分配。哦,没错,我记得它在Windows和Linux上的行为不同。。。最好不要这样做:D。
printf("%p", a[40]);
// prints out "1164"