Слайд 2Виды памяти
Существует три вида памяти: статическая, стековая и динамическая.
Статическая память выделяется
еще до начала работы программы, на стадии компиляции и сборки.
Слайд 3Статическая память
Существуют два типа статических переменных:
Глобальные переменные (определенные вне функций):
…
int
max_num = 100;
…
void main() {
…
}
Статические переменные (определенные со словом static):
void main() {
…
static int max = 100;
…
}
Слайд 4Локальные переменные
Локальные (или стековые) переменные – это переменные определенные внутри функции (или
блока):
void my_func() {
…
int n = 0;
…
if (n != 0) {
int a[] = {0, 2, 4, 5};
…
}
…
}
Память выделяется в момент входа в функцию или блок и освобождается в момент выхода из функции или блока.
Слайд 5Динамическая память
Недостаток статической или локальной памяти: количество выделяемой памяти вычисляется на этапе
компиляции и сборки.
Использование динамической памяти позволяет избавиться от данного ограничения.
Слайд 6Выделение и освобождение памяти
Выделение памяти:
void* malloc(size_t n);
n – размер памяти
в байтах
возвращаемое значение: указатель на выделенную память
Освобождение памяти:
void free(void *p);
p – указатель на память, которую необходимо освободить
Слайд 7Динамические массивы
Пример. Ввести с клавиатуры n чисел (n задается пользователем) и вывести
их в обратном порядке.
Неправильный способ решения задачи (с использованием локальной переменной массива) :
void main() {
int n,i;
scanf(“%d”, &n); /* вводим кол-во чисел */
int a[n]; /* ошибка. */
for (i = 0; i < n; i++)
scanf(“%d”, &a[i]);
for (i = n-1; n >=0; i--)
printf(“%5d”, a[n]);
}
Слайд 8Динамические массивы
Правильный способ решения задачи (с использованием динамической переменной массива):
void main() {
int n,i;
scanf(“%d”, &n); /* вводим кол-во чисел */
/* выделяем память под массив */
int *a = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; i++)
scanf(“%d”, &a[i]);
for (i = n-1; n >=0; i--)
printf(“%5d”, a[n]);
free(a); /* освобождаем память */
}
Слайд 9Динамические структуры
Выделение памяти под структуру:
struct <тэг структуры> *<имя переменной> =
(struct <тэг стр.>*) malloc(sizeof(<тэг стр.>));
Освобождение памяти:
free(<имя переменной>);
Опишем структуру:
struct student {
char name[50];
int grade;
int group;
};
Слайд 10Массивы динамически создаваемых структур
Пример. Формирование массива из динамически создаваемых структур.
void main()
{
/* Объявляем массив студентов */
struct student* a[100] = {NULL};
int i,n;
scanf(“%d”, &n); /* n - количество студентов */
for (i = 0; i < n; i++) {
/* резервируем память */
student[i] = (struct student*)malloc(
sizeof(student));
scanf(“%50s %d %d”, student[i]->name, &student[i]->age, &student[i]->grade);
}
…
}
Слайд 11Динамические массивы структур
Пример. Формирование динамического массива из структур.
void main() {
/*
Объявляем массив студентов */
struct student* a;
int i,n;
scanf(“%d”, &n); /* n - количество студентов */
/* резервируем память */
a = (struct student* a) malloc( n * sizeof(struct student a));
for (i = 0; i < n; i++) {
scanf(“%50s %d %d”, student[i].name, &student[i].age, &student[i].grade);
}
…
}
Слайд 12Динамические структуры данных
Использование динамической памяти позволяет создавать динамические структуры данных:
Cписки (однонаправленные и
двунаправленные)
Деревья
struct student {
char name[50];
int grade;
int group;
struct student* next; /* указывает на следующую
структуру */
};
Слайд 13Однонаправленный (односвязный) список
…
NULL
Начало списка
Слайд 14Двунаправленный список
next
student
next
student
next
student
…
NULL
Начало списка
previous
previous
previous
NULL
Конец списка