Динамическое распределение памяти

При программировании на языке Си может возникнуть ситуация, когда формально правильно написанная программа содержит некоторую серьёзную ошибку, которая может настолько повредить работе компьютера, что потребуется его перезагрузка. Поскольку программа написана формально верно, то компилятор ошибку не распознаёт. Рассмотрим пример подобной программы.

 

# include <std. LO . h>          
main ( ) г              
int *x, *w,y,z;          
  у=-15;              
  *х=16;              
  w= & у ;              
  printf( "n Размер указателя х составляет %d байт II 1
  sizeof( x) ) r          
  printf( "n Значение указателя х равно %и байт.", х) ;
  printf( "n Значение по этому адресу равно %d.",* х) ;
  printf( "n Адрес пе ременной у равен о U. • , &у) ;  
  printf( "n Адрес пе ременной z равен о U. • , &z) ;  
} printf( "n Значение *w равно - fed.", *w);    

Ошибка, содержащаяся в программе, одна из наиболее распространенных. По отдельности каждая строка программы правильна. Проблема заключается в не инициализированном указателе х. Объявление int *x приведёт к тому, что под переменную х выделется блок оперативной памяти. В нашем случае не выделен участок оперативной памяти для размещения числа 16. Получается, что 16 будет записано в неизвестную область памяти: поскольку переменная х не


инициализирована, то в ней хранится неизвестное число, и запись *х=6 приводит к тому, что по неизвестному адресу расположится число 16. Это может привести к следующему: 1) стирание части кода операционной системы, 2) стирание части кода драйвера или другой программы, 3) стирание кода самой выполняемой программы. Компилятор такую ошибку распознать не сможет.

Исправить ситуацию можно, если использовать функцию динамического распределения памяти malloc, прототип которой хранится в головном файле alloc.h. Функция malloc выделит в оперативной памяти два байта, в которых можно разместить целое число 16, и адрес этих двух байтов гарантированно не совпадает ни с одним из адресов, используемых операционной системой.

Таким образом, в исходную программу необходимо добавить две строки: 1) директиву препроцессора Mnclude <alloc.h> и 2) непосредственно перед оператором *х=16; строку x=(int*)malloc( sizeojiini));.

#include <stdio.h> #include <alloc.h> main( )

{

int *x,*w,y,z;

y=-15;

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

*x=16;

w= & у ;

printf("n Размер указателя х составляет %d байт.", sizeof(x));

printf("n Значение указателя х равно %u байт.", х); printf("n Значение по этому адресу равно %d.",*x); printf("n Адрес переменной у равен %u.", &y); printf("n Адрес переменной z равен %u.", &z); printf("n Значение *w равно %d.", *w) ; }

Описание функции malloc. Функция malloc динамически распределяет блок памями размером size байт. Возвращаемое значение — указатель на выделенную область памяти.

#include <alloc.h> void *malloc(size); unsigned size;