Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 数组元素超出绑定引用的位置?_C_Arrays - Fatal编程技术网

C 数组元素超出绑定引用的位置?

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 它可能指向

我想知道在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
它可能指向
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(无论它们是全局变量还是静态变量),它们可能不会连续存储在内存中?