C 数组元素超出绑定引用的位置?
我想知道在c语言中,如果我有一个长度为3的数组,如果我尝试访问数组的第4个元素,它将指向哪个内存地址 我读过类似的越界访问数组元素的问题,他们说这是一种典型的C 数组元素超出绑定引用的位置?,c,arrays,C,Arrays,我想知道在c语言中,如果我有一个长度为3的数组,如果我尝试访问数组的第4个元素,它将指向哪个内存地址 我读过类似的越界访问数组元素的问题,他们说这是一种典型的未定义行为,不安全,但是对于第四个元素所指向的位置是否有通用规则 例如,数组[3]在这里给出声明时会引用哪个内存地址 int a = 10; int array[3] = {1, 2, 3}; int b = 20; printf("%d", array[3]); // access the 4th element here 它可能指向
未定义行为
,不安全,但是对于第四个元素所指向的位置是否有通用规则
例如,数组[3]
在这里给出声明时会引用哪个内存地址
int a = 10;
int array[3] = {1, 2, 3};
int b = 20;
printf("%d", array[3]); // access the 4th element here
它可能指向a
或b
或array[x]
还是完全随机的
这里的关键点是:如果我在变量B之后声明变量A(特别是当它们是全局变量或静态变量时),它们会连续存储在内存中吗?还是完全依赖于编译器
它可能指向a或b或数组[x],还是完全随机的
完全随机:)
它可能指向a或b或数组[x],还是完全随机的
完全随机:)首先,为了澄清您所写的部分的原因,根据
C11
spec,您可以编写一个表达式,将元素的地址指定为最后一个元素的前一个,这很好,但您不能取消引用它。后者调用
考虑到array[3]
与*(array+3)
相同,引用了C11
标准,第§6.5.6章,加法运算符
[…]如果指针和
操作数和结果指向同一数组对象的元素,或超过最后一个的元素
数组对象的元素,求值时不应产生溢出;否则
行为是未定义的
及
如果结果指向数组对象的最后一个元素后一个元素,则
不得用作已计算的一元*
运算符的操作数
因此,总而言之,
(array+3)
将指向数组中最后一个元素的下一个位置(即&array[2]
),但该地址是a
还是b
的地址还是随机内存位置,完全取决于编译器,为了更清楚地说明您所写的部分的原因,根据C11
spec,您可以编写一个表达式,将元素的地址指定为超过最后一个元素的地址,这很好,但您不能取消引用它。后者调用
考虑到array[3]
与*(array+3)
相同,引用了C11
标准,第§6.5.6章,加法运算符
[…]如果指针和
操作数和结果指向同一数组对象的元素,或超过最后一个的元素
数组对象的元素,求值时不应产生溢出;否则
行为是未定义的
及
如果结果指向数组对象的最后一个元素后一个元素,则
不得用作已计算的一元*
运算符的操作数
因此,总而言之,
(array+3)
将指向数组中最后一个元素的下一个位置(即&array[2]
),但该地址是a
还是b
的地址还是随机内存位置,完全取决于编译器。这将是完全未定义的
事实上,由于这些变量是局部变量,它们可能位于堆栈上。但是,根据您的系统和/或编译器的不同,它们中的一些(例如本例中的a和b)可能存储在寄存器中,而不是存储在内存中
因此,您的
&array[3]
可能会指向堆栈空间中的某个位置,指向比&array[2]
更远的int,但它未定义为它将指向的值,访问它将/应该是非法的。这将是完全未定义的
事实上,由于这些变量是局部变量,它们可能位于堆栈上。但是,根据您的系统和/或编译器的不同,它们中的一些(例如本例中的a和b)可能存储在寄存器中,而不是存储在内存中
因此,您的
&array[3]
可能会指向堆栈空间中的某个位置,指向比&array[2]
更远的整数,但它未定义为它将指向的值,访问它将/应该是非法的。可能重复当您在某个位置读取未定义的行为时,您无法思考“通用规则”或者别的什么。在调试模式下,也许可以预测UB。在发行版中,编译器可以做它想做的任何事情。例如,它将删除未使用的a和b。还有数组。当你在某个地方读到未定义的行为时,你可能无法思考“通用规则”或任何东西。在调试模式下,也许可以预测UB。在发行版中,编译器可以做它想做的任何事情。例如,它将删除未使用的a和b。还有数组。数组[x]不是*(数组+x)的语法糖吗?在这种情况下,它不会指向堆栈中数组后面的下一个变量吗?@NadavL是的,但是下一个地址是a
还是b
的地址,这是不能保证的。是的,那么你的意思是如果我在变量b后面声明变量a(无论它们是全局变量还是静态变量),它们可能不会连续地存储在内存中?数组[x]不是*(数组+x)的语法糖吗?在这种情况下,它不会指向堆栈中数组后面的下一个变量吗?@NadavL是的,但是下一个地址是a
还是b
的地址,这是不能保证的。是的,那么你的意思是如果我在变量b后面声明变量a(无论它们是全局变量还是静态变量),它们可能不会连续存储在内存中?