ДИНАМИЧЕСКОЕ ВЫДЕЛЕНИЕ ПАМЯТИ

 

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

Можно создавать переменные и массивы по мере требования (необходимости), но затем, также необходимо очистить память, так как компилятор сделать это самостоятельно не может.

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

Функции создания динамических переменных и массивов объявлены в заголовочных файлах <alloс.h>, <stdlib.h>.

 

1. Функция void* malloc(размер) - выделяет в «куче» n байтов и возвращает указатель на 1-й байт, иначе возвращает 0. Необходимо делать преобразование типов.

 

Пример 1:

void* malloc(size_byte); //указатель на void

//создадим переменную целого типа; для этого определим указатель целого типа

int pt = (int)malloc(2); //или вместо 2 sizeof (int)

*pt=10;

 

Если нужно создать массив, то

float pt = (float) malloc(50*4) //или 50*sizeof(float)

 

Пример 2:

void main(void){

char *original=”Исходная строка”;

char *copy;

copy=(char*)malloc(strlen(original)+1);

if(copy==NULL) {

puts(“Ошибка выделения памяти”);

exit(1);

}

strcpy(copy,original);

cout<<copy<<endl; cout<<original<<endl;

free(copy);

}

Куча выделяет память. При выделении памяти она не очищается, там всегда хранится «мусор». Размер указывается в байтах.

 

2. Функция void* calloc(n,size type);

long* newmas = (long*)calloc(100,sizeof(long));

первый параметр - количество требуемых ячеек памяти (сколько переменных нужно создать);

второй параметр - размеp каждой ячейки (размер типа).

Функция calloc() обнуляет выделенную память.

 

Пример 1:

void* calloc(1, 2);

int pt = (int)calloc(1, 2); //одна переменная, по 2 байта каждая

*pt=10;

 

Пример 2:

void main ( ) {

char *original=”Сегодня четверг”;

char *copy; //создан указатель

copy = (char*)malloc(strlen(original)+1); //в скобках считаем сколько выделить памяти

 

Пример 3:

#define SIZE 128

void main(void) {

char *str=(char *)calloc(1,SIZE);

if(str==NULL) {

puts(“Ошибка выделения памяти”);

exit(1);

}

else {

cout<<”Введите строку”;

gets(str);

cout<<str;

free(s);

}

}

Может быть ситуация, что память не выделяется, например для массива. Массив требует для хранения непрерывного пространства, а если нет идущих подряд свободных ячеек, то массив не создается. Указатель возвращает нуль. Поэтому надо всегда проверять выделилась память или нет.

//Проверка выделения памяти

if (copy= = 0)

{

puts(“Ошибка выделения памяти”);

exit(1);

}

else

strepycopy (original);

puts (copy);

 

3. void* realloc(void *, n) - изменяет размер ранее выделенного блока памяти. Если дополнительная память выделяется в новом месте оперативной памяти, то уже введенная информация переписывается в новое место.

ptr = realloc(nptr, size);

где nptr - указатель на ранее выделенный блок; size размер дополнительно выделяемой памяти.

void main(void) {

char *p1, *p2;

puts(«Выделяем 128 байт»);

p1=malloc(128);

if(p1) {

puts(“Изменяем размер блока на 256 байтов”);

p2=realloc(p1,256); //блок теперь равен 256 байтам

}

if(p2)

free(p2);

else

free(p1);

}

 

4. void free(void *ptr) - освобождение выделенной памяти. Количество выделенной динамически памяти не может превышать 64 Кбайта - размера одного сектора.

 

Операция new и delete в С++

 

В С++ появились операции выделения динамической памяти и удаления (освобождения) динамической памяти.

Операции new и delete выполняют динамическое распределение и отмену распределения памяти, аналогично, но с более высоким приоритетом, нежели стандартные библиотечные функции семейства malloc и free.

Упрощенный синтаксис:

указатель-имени = new имя <инициализатор-имени>;

...

delete указатель-имени;

Имя может быть любого типа.

new пытается создать объект с типом "имени", распределив (при возможности) sizeof(имя) байт в свободной области памяти (которую также называют "кучей"). Продолжительность существования в памяти данного объекта - от точки его создания и до тех пор, пока операция delete не отменит распределенную для него память.

В случае успешного завершения new возвращает указатель нового объекта. Пустой указатель означает неудачное завершение операции (например, недостаточный объем или слишком большая фрагментированность кучи). Как и в случае malloc, прежде чем пытаться обращаться к новому объекту, следует проверить указатель на наличие пустого значения. Возвращаемый указатель будет иметь правильный тип, "указатель имени", без необходимости явного приведения типов.

name *nameptr // name может иметь любой тип, кроме функции

...

if (!(nameptr = new name)) {

errmsg("Недостаточно памяти для name");

exit (1);

}

...

delete nameptr; //удаление name и отмена выделения

//sizeof(name) байтов памяти

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

 








Дата добавления: 2016-02-02; просмотров: 995;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.011 сек.