2014-09-01 2 views
0

У меня есть следующий код в C:Присвоить массив междунар в C, но получил дополнительные ИНТ 32767

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? И я обнаружил weired вещь:

int main(){ 
    int arrayB[] = {7,4,3,4,1}; 
    for(int i = 0; *(arrayB+i); i++){ 
     printf("%d\n",*(arrayB+i)); 
    } 

}

Я написал это, и число 32767 появляется снова. И Жуткая часть, если я изменяю массив на любую другую длину (удалять или добавлять числа), он работал просто отлично !!!

+3

В C элементы вашего массива адресуются как [0], [1], ... [8] – Greycon

ответ

7

Вы получаете неопределенное поведение.

Вы не можете напечатать 10-й элемент 9-элементной диаграммы, это недопустимый код.

Вы получаете 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, вы получите неопределенное поведение.

+0

Так выразился, что это сбивает с толку. Массив имеет 9 элементов, и он пытается получить доступ к массиву [9], но это неверно, потому что в C первым элементом является массив [0], а 9-й - массив [8]. – Carles

+0

@Carles Спасибо, я неправильно подсчитал из-за запутанного '1,2,3,3, [...]' инициализатора. – unwind

+0

Нет проблем, это также случилось со мной на первый взгляд – Carles

0

Array индекс старт от 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] вы получите неопределенное поведение.

+2

Чтобы уточнить, он может не только содержать какое-либо значение, но также может привести к сбою программы. –

+0

@DrewMcGowen: Я не знал, что это может также сбой программы! Спасибо за информацию :) – user1336087

1

Массив имеет 9 действительные позиции, но вы должны принять во внимание, что они индексируются, начиная C на 0.

Итак, если вы хотите, чтобы первое значение: массив [0];

если вы хотите последнее значение: массив [8];

массив [9] не является допустимым положением.

Надеюсь, что это поможет.

1

В C, неинициализированные переменные получают значения мусора, который происходит в вашем случае, как массив [9] не определен, так как индексация в С начинается с 0 не 1.

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 

Это также хорошая идея, чтобы всегда компилировать все предупреждения включены.

Смежные вопросы