
- •Содержание
- •Лабораторная работа №9 классы хранения и видимость переменных
- •Теоретические сведения
- •Варианты индивидуальных заданий
- •Приложение 1
- •Лабораторная работа №10 препроцессорные средства
- •Теоретические сведения
- •1. Состав директив препроцессора и стадии препроцессорной обработки
- •2. Стадии препроцессорной обработки
- •3. Замены в тексте программы
- •4. Цепочка подстановок
- •5. Включение текстов из файлов
- •6. Условная компиляция
- •7. Операция defined
- •8. Макроподстановки средствами препроцессора
- •9. Моделирование многомерных массивов
- •10. Отличия макросов от функций
- •11. Препроцессорные операции в строке замещения
- •12. Вспомогательные директивы
- •13. Реакция на ошибки
- •14. Пустая директива
- •15. Встроенные (заранее определенные) макроимена
- •Варианты индивидуальных заданий
- •Лабораторная работа № 11 динамическое распределение памяти
- •Теоретические сведения
- •1. Функции malloc и free
- •2. Операторы new и delete
- •Варианты индивидуальных заданий
- •Лабораторная работа № 12 структура данных «список»
- •Теоретические сведения
- •1. Основные определения
- •2. Операции над списками
- •3. Пример реализации односвязного списка с помощью массива структур
- •4. Пример реализации двусвязного списка с помощью массива данных
- •Варианты индивидуальных заданий
- •Лабораторная работа №13 очереди. Операции над очередями. Деки
- •Теоретические сведения
- •1. Понятие очереди. Операции над очередями. Кольцевая очередь. Дек
- •2. Программная реализация очереди на основе массива
- •Варианты индивидуальных заданий
- •Лабораторная работа №14 стеки. Очереди. Операции над стеками и очередями
- •Теоретические сведения
- •1. Понятие стека. Операции над стеком
- •2. Программная реализация стека на основе массива
- •Варианты индивидуальных заданий
- •Лабораторная работа №15
- •Анализ пузырьковой сортировки. Пузырьковая сортировка обладает несколькими характеристиками:
- •2. Сортировка методом выбора
- •3. Сортировка методом вставки
- •4. Сортировка методом Шелла
- •5. Сортировка методом Хоора
- •6. Алгоритмы поиска
- •Варианты индивидуальных заданий
- •Приложение 2
- •Лабораторная работа №16 программирование алгоритмов вычислительной математики
- •Теоретические сведения
- •1. Методы Симпсона
- •Варианты индивидуальных заданий
- •Литература
Лабораторная работа № 11 динамическое распределение памяти
Цель: Изучить способы распределения памяти в программах на языке Си, функции библиотеки Си для динамического распределения памяти, операторы new и delete языка С++. Разобрать приведенные примеры и выполнить один или более вариантов заданий.
Теоретические сведения
Память для хранения данных может выделяться статически и динамически. Статическое распределение памяти выполняется на этапе компиляции. Компилятор по имени и типу объектов отводит для них место в результирующем exe-файле в разделе сегмента данных (или стеке).
Чаще при программировании неизвестно, какого размера массивы, структуры или другие данные будут необходимы для работы программы. В этом случае необходимо для хранения данных использовать специальный раздел памяти, называемый «кучей» (heap). Куча располагается вне любой программы, объём кучи и её месторасположение зависят от модели памяти.
В библиотеке функций языка Си существует ряд функций, выполняющих динамическое распределение памяти. Основные функции представлены в табл. 11.1.
Таблица 11.1.
Функции библиотеки Си для динамического распределения памяти
Функция распределения |
Функция освобождения |
Функция перераспределения |
Malloc |
Free |
Realloc |
Calloc |
Free |
Realloc |
Функция malloc запрашивает у операционной системы определенное число байт памяти, функция calloc отличается от malloc параметрами, она запрашивает у операционной системы блок из некоторого числа элементов определенного размера. Функция realloc меняет разделы выделенного блока.
Адрес начала выделенной памяти возвращается в точку вызова функции. Если выделенный участок памяти больше не требуется, он должен быть освобождён с помощью функции free в том же блоке, где и запрошен, иначе эта память оказывается недоступной для дальнейшего распределения.
1. Функции malloc и free
Формат malloc:
указатель = (тип) malloc (количество байт);
Формат free:
free(указатель);
Пример 11.1
Выполнить распределение и освобождение памяти для двух чисел типа int и адрес начала поместить в указатель num.
int * num; //объявление указателя
num=(int*) malloc(2); //выделение памяти
free(num); //освобождение памяти
Пример 11.2
Выделить память под строку из 20 символов, инициализировать ее и вывести на экран. Освободить память.
#include<stdio.h>
#include<string.h>
# include <stdlib.h>
void main(void)
{ char *stroka;
stroka=(char *) malloc(20); //выделение памяти
strcpy(stroka,"Good luck!"); //инициализация строки
printf("%s\n", stroka); //вывод на экран
getchar();
free(stroka); //освобождение памяти
}
Пример 11.3
Выделить память под структуру student, состоящую из 3 полей: массива фамилий, массива адресов e-mail, массива номеров телефонов.
#include<stdlib.h>
struct student
{ char name[40];
char mail[40];
char phone[40];
};
struct student *get_mem(void)
{ struct student * sp;
sp=(struct student *)malloc(sizeof(student));
if(!sp)
{ printf(“Allocation error.”); exit(1); }
return sp;
}
void main(void)
{ struct student * Alisa;
Alisa = get_mem();
strcpy(Alisa ->name,"Alisa");
strcpy(Alisa -> mail,"Alisa@tut.by ");
strcpy(Alisa -> phone,"666 66 66");
printf(“%s\n”, Alisa ->mail);
getchar(); }
В настоящем примере проводится проверка корректности выделения памяти для указателя sp. Если память не выделена, то значение указателя равно нулю и следует проанализировать эту ситуацию и предусмотреть аварийную обработку.
Пример 11.4
Задать массив из 100 строк через указатель. Зарезервировать память 128 символов под каждую строку массива. Освободить зарезервированную память.
int main(void)
{
char *str[100];
int i;
for(i=0; i<100; i++)
{
str[i]=(char*)malloc(128);
if(str[i]==NULL)
{
printf(“Alocation error.”); exit(1);
}
}
for(i=0; i<100; i++) free(str[i]); //освобождение памяти
return 0;
}