我只是在刷新我的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.如果有人能提供一些解释我会非常感激。
感谢。
答案 0 :(得分:10)
从技术上讲,它是未定义的行为,这意味着任何事情都可能发生,不一定是分段错误。
只是你的程序不是一个有效的程序,你不应该编写无效的程序,并期望它们有效/无效的行为。
答案 1 :(得分:6)
你可以随时获得分段错误,这次你“幸运”了。这是 undefined 行为,因此您可能会在其他时间遇到seg错误。
C做不做任何边界检查,所以虽然Java会抱怨,但C很乐意做任何你要求它做的事情,甚至对程序本身的不利。
这既是其主要优势之一,也是弱点。
答案 2 :(得分:3)
您的计划有undefined behaviour。这并不意味着它可以保证是段错误的。失败可能以其他方式表现出来(或根本不存在)。
答案 3 :(得分:2)
根据我对内存如何分配的理解,这是我的猜测(可能是错误的 - 如果是这样的话,请将其投票!):
arr[3]
的地址位于您的应用有权写入的内存页面中。我认为4KB是一种常见的页面大小。 malloc
调用导致1个页面被映射到您的应用,其中您只使用了第一个3*sizeof(*arr)
个字节,因此在arr[2]
之后您的应用有权允许写信,但malloc
尚未发布。如果您要执行另一个malloc
,则返回的地址将大于arr
,并且可能等于arr[3]
的地址。