[英]Assign a array of int in C but got an extra int 32767
我在C中有以下代码:
int main(){
int array[] = {1,2,3,3,4,5,6,7,8};
printf("%d\n", array[8]);
printf("%d\n", array[9]);
}
当我执行它时,我得到的结果是8和32767。我很困惑为什么。
更新
抱歉3,3的事情。 真正让我困惑的是数字32767,如果它是未定义的行为,为什么总是32767? 我发现了一件奇怪的事情:
int main(){
int arrayB[] = {7,4,3,4,1};
for(int i = 0; *(arrayB+i); i++){
printf("%d\n",*(arrayB+i) );
}
}
我写了这个,并且数字32767再次出现。 和令人毛骨悚然的部分是,如果我将数组更改为任何其他长度(删除或添加数字),它就可以正常工作!!!
您得到不确定的行为。
您无法打印9个元素的数组的第十个元素,这不是有效的代码。
array[8]
只得到8
,因为初始化列表中有3
次两次。
您的数组在内存中看起来像这样:
+---+---+---+---+---+---+---+---+---+
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
data: | 1 | 2 | 3 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
因此,您可以看到array[8]
上的数据实际上是8,但这是数组中的最后一个元素。 如果使用大于8
索引进行索引,则会出现未定义的行为。
该数组有9个有效位置,但是您必须考虑到它们在C中从0开始的索引位置。
因此,如果您想要第一个值:array [0];
如果您想要最后一个值:array [8];
array [9]不是有效位置。
希望能有所帮助。
在C中,未初始化的变量会得到垃圾值,这在您的情况下会发生,因为未定义array [9],因为C中的索引从0而不是1开始。
在C语言中,数组元素的计数从零到长度减去一。 如果使用GCC编译器,则可以添加选项-fsanitize=address
来检测像这样的一次性错误。
资源:
$ cat test.c
#include <stdio.h>
int main(void)
{
int array[] = {1, 2, 3, 3, 4, 5, 6, 7, 8};
printf("%d\n", array[8]);
printf("%d\n", array[9]);
return 0;
}
编译命令:
$ gcc -ansi -g -pedantic -Wall -fsanitize=address -o test test.c
输出:
$ ./test
8
=================================================================
==4517== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff70a43794 at pc 0x400b2b bp 0x7fff70a43740 sp 0x7fff70a43738
READ of size 4 at 0x7fff70a43794 thread T0
#0 0x400b2a (/tmp/test+0x400b2a)
#1 0x7f1ff1180ec4 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21ec4)
#2 0x400788 (/tmp/test+0x400788)
Address 0x7fff70a43794 is located at offset 68 in frame <main> of T0's stack:
This frame has 1 object(s):
[32, 68) 'array'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
0x10006e1406a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e1406b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e1406c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e1406d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e1406e0: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
=>0x10006e1406f0: 00 00[04]f4 f4 f4 f3 f3 f3 f3 00 00 00 00 00 00
0x10006e140700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e140710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e140720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e140730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e140740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap righ redzone: fb
Freed Heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==4517== ABORTING
始终编译所有警告也是一个好主意。
数组索引从0
开始。 因此,您不应访问第十个元素。
array[0] is storing 1.
array[1] is storing 2.
array[2] is storing 3.
array[3] is storing 3.
array[4] is storing 4.
array[5] is storing 5.
array[6] is storing 6.
array[7] is storing 7.
array[8] is storing 8.
当您尝试访问array[9]
您将获得未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.