2015-05-04 5 views
1

Следующая программа C создает массив с фиксированным числом элементов. Даже когда мы назначаем еще три значения, которые превышают количество элементов максимального массива, отлично работают.Инициализация массивов в C

#include <stdio.h> 

int main(){ 

//declares a fixed sized array 
int balance[5]; 

//initializing 
balance[0] = 1; 
balance[1] = 2; 
balance[2] = 3; 
balance[3] = 4; 
balance[4] = 5; 
//three more 
balance[5] = 6; 
balance[6] = 7; 
balance[7] = 8; 


printf("%d \n", balance[0]); 
printf("%d \n", balance[1]); 
printf("%d \n", balance[2]); 
printf("%d \n", balance[3]); 
printf("%d \n", balance[4]); 
printf("%d \n", balance[5]); 
printf("%d \n", balance[7]); 

//and it works fine! 

return 0; 
} 

Но когда мы пытаемся присвоить более чем три элемента он вызывает исключение

#include <stdio.h> 

int main(){ 

//declares a fixed sized array 
int balance[5]; 

//initializing 
balance[0] = 1; 
balance[1] = 2; 
balance[2] = 3; 
balance[3] = 4; 
balance[4] = 5; 
//three more 
balance[5] = 6; 
balance[6] = 7; 
balance[7] = 8; 
//one more again 
balance[8] = 9; 


printf("%d \n", balance[0]); 
printf("%d \n", balance[1]); 
printf("%d \n", balance[2]); 
printf("%d \n", balance[3]); 
printf("%d \n", balance[4]); 
printf("%d \n", balance[5]); 
printf("%d \n", balance[7]); 
printf("%d \n", balance[8]); 

//throws an exception! 

return 0; 
} 

Но после объявления и инициализации массива с помощью целочисленных литералов можно вставить несколько элементов, не получая ошибку.

#include <stdio.h> 

int main(){ 

//declares and initialize a fixed sized array 
int balance[5] = {1,2,3,4,5}; 

//let's add few more 
balance[5] = 6; 
balance[6] = 7; 

//and even more 
balance[7] = 8; 
balance[8] = 9; 
balance[9] = 10; 

printf("%d \n", balance[0]); 
printf("%d \n", balance[1]); 
printf("%d \n", balance[2]); 
printf("%d \n", balance[3]); 
printf("%d \n", balance[4]); 
printf("%d \n", balance[5]); 
printf("%d \n", balance[6]); 
printf("%d \n", balance[7]); 
printf("%d \n", balance[8]); 
printf("%d \n", balance[9]); 

//and it works fine! 

return 0; 
} 

В чем причина такого поведения языка C?

+3

Неопределенное поведение –

+5

Причина в том, что все утверждения, которые используют элементы доступа «a [5]» и «за», являются неопределенным поведением, что не является гарантией отказа. Перестаньте пытаться выяснить, как далеко вы можете пойти и научиться распознавать и избегать подобных случаев. –

+0

Что значит «выкидывает исключение» * ?? Может быть, вы компилируете C-код с помощью компилятора C++? – pmg

ответ

1

Вы получаете доступ к нераспределенной памяти, которая будет вызывать неопределенное поведение. Может произойти все, что угодно. Все они находятся вне доступа.

balance[5] = 6; 
balance[6] = 7; 
balance[7] = 8; 
balance[8] = 9; 
+0

Спасибо за объяснение. –

1

Массив из ограниченного доступа приводит к неопределенному поведению. Ваш массив может содержать 5 целых элементов, поэтому действительный индекс для вашего массива - 0 - 4 - все, кроме этого, представляет собой массив из ограниченного доступа.

+0

Спасибо за объяснение. –

1

Ваш код вызывает Undefined Behavior при попытке доступа к массиву за пределами границ, что является небезопасной памятью, и, следовательно, результат не определен.

+0

Спасибо за объяснение. –

1

Я хотел бы дать более общий ответ. Все здесь получили «правильный ответ», но я хочу объяснить, почему & будет немного более длинным относительно объяснения. Предположим, у вас есть массив символов из 3 случаев.

char tab[3]; 

С точки зрения памяти, мы получили 3 случая передачи данных. Поскольку это массив, он выровнен в вашей памяти. Давайте инициализирует этот массив:

tab[0] = 'A'; 
tab[1] = 'B'; 
tab[2] = 'C'; 

В вашей памяти, это выглядит примерно так:

enter image description here

Теперь, что произойдет, если вы пишете tab[6]? Поскольку это C, вы можете четко это сделать, никаких проблем. (Нет electric-fence;))

В этом случае вкладка [6] не была назначена вашей программе. Вы можете иметь любой сценарий теперь:

  • Может быть, эти данные критик в систему, и ваша программа не будет иметь доступ к этой памяти (т.е. Сегментация Fault)
  • Может быть, ваша программа имеет другой массив где-нибудь, и вы могли бы получить удачу вничью и фактически получить что-то оттуда.
  • (другие вещи хуже этого)
  • ???

В основном, когда вы спровоцировать Из Bounds ошибки, вы привести к непредсказуемому поведению. То, что вы должны делать, - это всегда следить за ошибками, которые могут быть смертельными убийцами вашего любимого приложения.

+0

Спасибо за объяснение. –

+0

@RasanSamarasinghe вы можете выбрать ответ, который соответствует вашему вопросу! – Mekap

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