2012-03-06 3 views
-7

Это вопрос одного из сайтов кодирования ....Распределение памяти массива

Замените "?" с целым числом, так что выход равен 4.

int main() 
{ 
    int arr[7]; 
    int b,c,d,a; 
    a=4; 
    printf("%d",arr[?]); 
    return 0; 
} 

Я попытался понять это и нашел, что ответ будет -4. Теперь, если я объявляю еще одну переменную (например, int b, c, d, e, a в строке 4 кода), ответ получился равным -5.

Пожалуйста, объясните, как работает компилятор, и причина распределения памяти (отрицательные индексы).

+5

Там нет правильного ответа на этот вопрос - вы может быть в состоянии найти значение, которое дает желаемый результат, но оно будет специфичным для компилятора и специфичным для архитектуры и будет полагаться на неопределенное поведение. –

+0

Ну, вы не инициализировали 'arr', чтобы вы никогда не знали! –

+1

Тот, кто задал вам этот вопрос, не знает программирования на С. – Lundin

ответ

2

Во-первых, предостережение: НИКОГДА не пишите ни одного кода, который будет использовать этот тип поведения, так как он будет отличаться от компилятора к компилятору.

Редактирование: поскольку первый абзац явно не был достаточно ясным: доступ к массиву за пределами поля - неопределенное поведение, что означает, что компилятор может создать программу, которая делает все, что выбирает компилятор. Здесь я объясняю , что, возможно, составитель компилятора плаката сделал, но также может быть, что результат будет 4 случайно.

Ваш компилятор, видимо, выбрал выложить переменные следующим образом (при условии, что первая переменная заканчивается по адресу 100):

  • 100: a
  • 104: d
  • 108: c
  • 112: b
  • 116: arr[0]
  • 120: arr[1]
  • ...
  • 140: arr[6]

С arr начинается на 116, а размер каждого из его элементов (int) составляет 4 байта, arr[-4] находится на 116 + 4 * (-4) = 100, где находится a.

+0

Это неопределенное поведение, компилятор не гарантированно дает какой-либо разумный вывод вообще из этого кода, и программе разрешено сбой и запись. Вы не можете получить доступ к массиву вне пределов, просто так. – Lundin

+0

Для всего, что мы знаем, компилятор, возможно, тоже не сделал этого. Возможно, в ячейке памяти [-4] был случайный 4, и он просто щелкнул здесь. Это также возможно? Но, с другой стороны, является ли это тем, что если бы компилятор не поставил переменные в предложенном вами способом, было бы какое-либо исключение? Просто любопытно узнать. Спасибо – Jay

+0

@ Lundin, правда? Это неопределенное поведение? Не мог догадаться, прочитав еще 10 комментариев, заявив одно и то же! Гай просто пытается представить случай, который имел наибольшую вероятность. – jn1kk

1

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

Когда вы это делаете, вы получаете доступ к другим позициям в памяти. В этом примере, следующие 4 позиции зарезервированы для Int переменных b, c, d и a

Таким образом, вы получаете из массива и в пространстве переменных.

Во всяком случае, это может быть, что это зависит от компилятора/архитектуры, но я бы ожидал, что правильный ответ будет 11 (размер массива + 4 переменных)

+0

О, и другие комментарии верны. Это по своей сути небезопасно, и единственная причина, по которой вы можете сделать это в C, состоит в том, что предполагается, что вы этого не сделаете, и поэтому программа не проверяет значения (поэтому она становится немного быстрее). Никогда не используйте код, подобный этому IRL – SJuan76