2012-06-10 3 views
4

Я просто немного освежил свои понятия C, где я запутался в каком-то поведении. Рассмотрим следующий фрагмент кода:Динамическая путаница массива

#include<stdio.h> 
#include<stdlib.h> 

int main(){ 


    int * arr; 
    arr= malloc(3*sizeof(*arr)); 
    arr[0]=1; 
    arr[1]=2; 
    arr[2]=3; 
    arr[3]=4; 
    printf("value is %d \n", arr[3]); 

return 0; 


} 

Проблема в том, что программа функционирует правильно! Насколько я понимаю, я выделяю память для массива из 3 целых чисел. Поэтому в основном, когда я пытаюсь поместить значение в arr[3], должно быть segmentation fault, так как для него не было присвоено никакой памяти. Но он отлично работает и печатает значение 4. Либо это какое-то странное поведение, либо я серьезно нуждаюсь в пересмотре базового C. Пожалуйста, если кто-нибудь может предложить какое-то объяснение, я бы очень признателен ему. Спасибо.

+2

уже видел так много раз: возможно дубликат [Массив больше выделенного?] (Http://stackoverflow.com/questions/8057584/array-is-larger-than-allocated) –

+0

Согласен. Этот или подобный вопрос, кажется, публикуется каждые несколько дней. –

ответ

10

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

+0

Получил это. благодаря :) – Abdullah

3

Ваша программа имеет undefined behaviour. Это не означает, что он гарантирован segfault. Неспособность может проявляться другими способами (или вовсе не).

6

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

C не делать какие-либо проверки границ, так что, например, Java жаловался бы, C очень рад сделать все, что вы просите, чтобы это делалось даже в ущерб самому программному обеспечению.

Это и одна из основных сильных сторон, а также недостатки.

2

Вот мое предположение основано на моем понимании того, как выделяется память (это может быть неправильно - так голосовать его вниз, если это!):

Адрес arr[3] находится на странице памяти, что ваше приложение имеет разрешение написать. Я думаю, что 4KB - это общий размер страницы. Вызов malloc привел к тому, что 1 страница была сопоставлена ​​с вашим приложением, из которых вы используете только первые байты 3*sizeof(*arr), поэтому после arr[2] есть место, которое ваше приложение имеет разрешение на запись, но malloc еще не опубликовано. Если вам нужно было выполнить еще один malloc, то возвращаемый адрес будет больше arr и может быть равен адресу arr[3].

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