4

我只是稍微复习一下我的 C 概念,因为我对某些行为感到困惑。考虑以下代码片段:

#include<stdio.h>
#include<stdlib.h>

int main (){


    int * arr;
    arr= malloc(3*sizeof(*arr));
    arr[0]=1;
    arr[1]=2;
    arr[2]=3;
    arr[3]=4;
    printf("value is %d \n", arr[3]);

return 0;


}

问题是程序运行正常!据我了解,我为 3 个整数的数组分配内存。所以基本上当我尝试输入一个值时arr[3] 应该有一个segmentation fault,因为没有为它分配内存。但它工作正常并打印值 4。要么这是一些奇怪的行为,要么我真的需要修改基本的 C。如果有人能提供一些解释,我将不胜感激。谢谢。

4

4 回答 4

10

从技术上讲,它是未定义的行为,这意味着任何事情都可能发生,不一定是分段错误。
只是您的程序不是有效程序,您不应编写无效程序并期望它们具有有效/无效的行为。

于 2012-06-10T12:07:19.697 回答
6

您随时可能遇到分段错误,这次您“幸运”了。这是未定义的行为,因此您可能会在其他时候遇到段错误。

C不做任何边界检查,所以尽管 Java 会抱怨,但 C 很乐意做任何你要求它做的事情,即使对程序自身不利。

这既是它的主要优势之一,也是它的弱点。

于 2012-06-10T12:07:49.447 回答
3

您的程序有未定义的行为。这并不意味着它可以保证段错误。失败可能以其他方式表现出来(或根本不表现出来)。

于 2012-06-10T12:07:22.210 回答
2

这是基于我对内存分配方式的理解的猜测(可能是错误的 - 如果是,请投反对票!):

的地址arr[3]位于您的应用有权写入的内存页面中。我认为 4KB 是常见的页面大小。该malloc调用导致 1 个页面被映射到您的应用程序,您只使用其中的第一个3*sizeof(*arr)字节,因此arr[2]您的应用程序有权写入,但malloc尚未发布。如果您要执行另一个malloc,返回的地址将大于arr并且可能等于arr[3].

于 2012-06-10T12:58:27.283 回答