2012-06-10 102 views
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.请任何人都可以提供一些解释我会高度赞赏它。 谢谢。

+2

已经看过这么多次:[数组大于分配?]可能重复(http://stackoverflow.com/questions/8057584/array-is-larger-than-allocated) –

+0

我同意。这个或类似的问题似乎每隔几天就会发布一次。 –

回答

10

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

+0

明白了。谢谢 :) – Abdullah

3

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

6

您可能随时都会遇到分段错误,这次你得到了“幸运”。这是undefined行为,所以您可能会在其他时间出现seg故障。

C确实不是做任何边界检查,所以,例如,Java会抱怨,C很乐意做你所要求的任何事情,甚至对程序自己的损害。

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

2

这是基于我的内存是如何分配的理解我的猜测(它可能是错的 - 因此将其否决,如果它是!):

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