我只是在对某些行为感到困惑的地方稍微复习一下我的 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。如果有人能提供一些解释,我将不胜感激。谢谢。
从技术上讲,它是未定义的行为,这意味着任何事情都可能发生,不一定是分段错误。
只是你的程序不是有效的程序,你不应该编写无效的程序,并期望它们有有效/无效的行为。
你随时都可能遇到分段错误,这次你很"幸运"。这是未定义的行为,因此您可能会在其他时间遇到 seg 错误。
C不做任何边界检查,所以虽然 Java 会抱怨,但 C 很乐意做你要求它做的任何事情,即使对程序本身不利。
这既是它的主要优势之一,也是它的弱点。
您的程序具有未定义的行为。这并不意味着它保证段错误。失败可能以其他方式表现出来(或根本不表现出来)。
这是我根据我对内存分配方式的理解做出的猜测(这可能是错误的 - 所以如果是的话,请投票反对!
arr[3]
的地址位于应用有权写入的内存页中。我认为 4KB 是一个常见的页面大小。malloc
调用导致 1 个页面映射到你的应用,你只使用其中的前 3*sizeof(*arr)
个字节,因此你的应用有权写入arr[2]
之后还有剩余的空间,但malloc
尚未发出。如果要执行另一个malloc
则返回的地址将大于 arr
,并且可能等于 arr[3]
的地址。