Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014_2015 / LECT7_new1.pptx
Скачиваний:
9
Добавлен:
27.12.2015
Размер:
1.12 Mб
Скачать

Динамически распределяемую память следует использовать в случае если мы заранее (на момент написания программы) не знаем сколько памяти нам понадобится (например, размер массива зависит от того, что введет пользователь во время работы прог-раммы) и при работе с большими объемами данных (например, массив из 1 000 000 int не влезет в стек).

Функции стандартных библиотек для работы с динамической памятью

void *malloc(size_t size); (alloc.h)

В качестве входного параметра функция принимает размер памяти, которую требуется выделить. Возвращаемым значением является указатель на выделенный в куче участок памяти.

Пример: выделение памяти под 1 000 000 int: int * p = malloc(1000000*sizeof(int)); - в С

В С++ нет неявного приведения указателей: int * p = (int *) malloc(1000000*sizeof(int));

Если ОС не смогла выделить память (например, памяти не хватило), то malloc возвращает 0.

После окончания работы с выделенной динамически памятью нужно освободить ее - ф-я free возвращает память под управление ОС.

void free(void *ptr); (alloc.h)

В качестве входного параметра в free нужно передать указатель, значение которого получено из функции malloc. Вызов free на указателях, полученных не из malloc (например, free(p+10)), приведет к неопределенному поведению, т.к. при выделении памяти при помощи malloc в ячейки перед той, на которую указывает возвращаемый функцией указатель операционная система записывает служебную информацию. При вызове free(p+10) информация находящаяся перед ячейкой (p+10) будет трактоваться как служебная.

Пример:

#include<string.h>

#include<stdio.h>

#include<alloc.h> int main(void)

{

char *str;

/* выделить память под строку */ str = malloc(15);

/* скопировать в строку "Student Petrov" */ strcpy(str," Student Petrov ");

/* вывести строку */ printf("Строка: %s\n",str); /* освободить память */ free(str);

return 0;

}

void *calloc(size_t nmemb, size_t size); (alloc.h)

Ф-я работает аналогично malloc, отличается син-таксисом (вместо размера выделяемой памяти нужно задать количество элементов и размер одного элемента) и обнулением выделенной памяти.

Например, после выполнения

int * q = (int *) calloc(1000000, sizeof(int))

q будет указывать на начало массива из миллиона инициализированных нулями чисел типа int.

void *realloc(void *ptr, size_t size); (alloc.h)

Ф-я изменяет размер выделенной памяти (на которую указывает ptr, полученный из вызова malloc, calloc или realloc). Если указанный в параметре size размер больше, чем тот, который был выделен под указатель ptr, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделен-ными. Если места недостаточно, то выделяется новый участок памяти размером size и данные по указателю ptr копируются в начало нового участка. Если ptr является нулевым указателем, realloc работает также как и malloc.

Возвращаемое значение: возвращает адрес блока, который

может отличаться от исходного. Если блок не мо-жет быть выделен или size равно 0, то возвращает NULL. Переносимость: realloc доступна в системах UNIX и поддерживается стандартом ANSI C.

Пример:

#include<stdio.h>

#include<string.h>

#include<alloc.h> int main(void)

{char *str;

str = malloc(10); /* выделить память под строку */ strcpy(str,"Student"); /*скопировать в строку "Student" */ /* вывести строку */

printf("String: %s\n, address: %p\n",str,str); str = realloc(str,20);

printf(" String: %s\n, new address:: %p\n",str,str); free(str); /* освободить память */

return 0;

}

Структуры и объединения – один из примеров

составных типов данных, называемых агрегатными типами.

Структурные переменные (структуры) – это объединение одной или более переменных, возможно, разных типов, в одну область памяти, имеющую одно имя. Отдельные составные части структурной переменной называются полями.

Объединения (кучи) подобны структурам в том, что содержат поля различных типов, но помещаемые в одно и то же место памяти. Фактически объединения

– это доступ к одному и тому же месту памяти, но по- разному.

Термин "структура" в C++ (C) 2м разным понятиям:

1)обозначение места в памяти, где располагается информация; это место называется структурной переменной;

2)правила формирования структурной переменной,

используемые компилятором для выделения ей места в

Как и любая переменная, структурная переменная

должна описываться. Ее описание состоит из 2х шагов:

1)задание шаблона структуры;

2)собственно описание структурной переменной.

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

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

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

Синтаксис задания шаблона таков:

struct имя_шаблона

{

тип_1 имя_поля_1; тип_2 имя_поля_2;

•••

тип_N имя_поля_N;

};

имя_шаблона – имя шаблона, удовлетворяющее правилам задания идентификаторов языка С++ (С); тип_1, тип_2,..., тип_N – любые типы, например int, char, float;

имя_поля_1, имя_поля_2, ..., имя_поля_N – имена полей, удовлетворяющие правилам задания идентификаторов языка С++ (С).

Пример. Структура Patient, которая может

использоваться при каталогизации медицинских карт :

struct Patient

{

int PatientID;

char * PatientFamily; char * PatientName; char * PatientSecName; int year;

char * Diagnosis; int DiagnosisID;

}; Имена полей в одном шаблоне должны быть

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

может и совпадать с именами полей, переменных или

Задание шаблона не связано с резервированием

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

Фактически шаблон – это задание нового типа struct имя_шаблона. В приведенном примере был введен новый тип struct Patient.

Как и простая переменная, шаблон имеет область определения (видимость). Если шаблон описан внутри блока {}, – это локальный шаблон, видимый только из пределов данного блока, в частности из пределов конкретной функции. Если описание шаблона помещено вне блоков, такой шаблон видим во всех функциях ниже точки описания шаблона до границы файла. Нельзя описать шаблон с реквизитом extern.

Соседние файлы в папке 2014_2015