2015-09-29 2 views
1

Я пытаюсь понять вывод следующего кода.Понимание инкремента malloc и указателя с бесплатным

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

main() 
{ 
    int *p = (int *) malloc(sizeof(int)); 
    *p = 42; 
    *(p+1) = 41; 

    printf("%d -- %d\n", *p, p); 
    printf("%d\n", p[0]); 
    printf("%d -- %d\n", p[1], p+1); 

    free(p); 

    printf("%d --- %d\n", *p, p); 
    printf("%d --- %d\n", p[1], p+1); 
} 

Мое понимание, шаг за шагом, заключается в следующем:

int *p = (int *) malloc(sizeof(int)); 

р теперь указывает на блок памяти, возвращаемой таНос.

*p = 42; 

магазин значение в месте, возвращаемого таНос.

*(p+1) = 41; 

магазин значение в том месте, непосредственно примыкающем к тому, что возвращает таНоса.

free(p); 

Свободное пространство указывает р, который первоначально был получен вызовом таНос, то есть, расположение ИНТ .

Результаты:

42 -- 14327824 
42 
41 -- 14327828 
0 --- 14327824 
0 --- 14327828 

Я понимаю, что адрес был возвращен таНос. Когда оператор

*(p+1) = 41;
выполняется, значение было сохранено в блоке не возвращается по таНосу, т.е. р +-.

Когда свободный называется, Я понимаю, что оно освобождает пространство, на который указывает р, то есть, значение . Почему же тогда сохраняется значение, сохраненное в p + 1?

Кроме того, если таНос возвращает указатель пт к блоку неинициализированного хранения. Является ли местоположение pt + 1 за пределами зоны хранения, установленной malloc?

+1

Прикосновение к памяти вне того, что вы выделяете, дает неопределенные результаты – stark

+0

Этот оператор '* (p + 1) = 41;' приводит к * неопределенному поведению *. Местоположение вашей памяти 'p + 1' не выделяется вашей программой. –

+1

Причина, по которой вы можете сохранить значение в 'p + 1', вероятно, потому, что ваша реализация' malloc' выделила немного больше места, чем вы просили. Возможно, что он выделяет память, например, в 16 раз. – Adrian

ответ

1

Что вы делаете, это неопределенное поведение.

int *p = (int *) malloc(sizeof(int)); 

Это выделяет sizeof(int) байтов, начиная с адреса, возвращенного malloc.

Когда вы

*(p+1) = 41; 

вы разыменования в ячейку памяти, которая не была выделена в куче.Его адрес: p + sizeof(int), который является неуправляемым адресом.

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

+0

Я не согласен с последним предложением. Вы действительно можете сделать выводы о том, что делает ваш компилятор с неопределенной ситуацией, но это поведение может измениться в любое время, когда что-то другое изменится: другие параметры или версия компилятора и т. Д. Но может быть интересно сделать выводы только для изучения и расширения вашего горизонта , Однако, если вы говорите о производственных программах, вы правы. Для них это должно быть неуместным, поскольку в них следует избегать таких конструкций. – glglgl

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