在C中分配一个int数组但得到一个额外的int 32767

时间:2014-09-01 14:17:48

标签: c arrays pointers

我在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号又出现了。和令人毛骨悚然的部分是如果我将数组更改为任何其他长度(删除或添加数字),它工作得很好!

5 个答案:

答案 0 :(得分:7)

你得到了未定义的行为。

你不能打印9元素arrray的第10个元素,这是无效的代码。

8只获得array[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的索引进行索引,则会得到未定义的行为。

答案 1 :(得分:1)

该数组有9个有效位,但您必须考虑它们在C中以0开始编入索引。

所以如果你想要第一个值:array [0];

如果你想要最后一个值:array [8];

array [9]不是有效位置。

希望有所帮助。

答案 2 :(得分:1)

在C中,未初始化的变量得到垃圾值,这种情况发生在你的情况下,因为没有定义数组[9],因为C中的索引从0开始而不是1。

答案 3 :(得分: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

在启用所有警告的情况下始终进行编译也是一个好主意。

答案 4 :(得分:0)

数组索引从0开始。所以你不应该访问第10个元素。

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]时,您将获得未定义的行为。