Тёмный

Практика языка C (МФТИ, 2023-2024). Углубление пройденного: логическая память и виртуальная память. 

Konstantin Vladimirov
Подписаться 20 тыс.
Просмотров 8 тыс.
50% 1

Практические занятия по языку C на первом курсе МФТИ. Кафедра информатики.
Мы временно берем передышку. На этом семинаре не будет новых задач. Только углубление понимания концепции памяти, которая очень нам понадобиться дальше. Начнём мы со своего рода мультфильма, который называется Genesis и к которому мы вернемся на втором курсе, см. • Базовый курс C++ (MIPT...
Семинарист: Константин Владимиров.
Дата: 13 октября 2023 года.
Съёмка: Марк Гончаров.
Звук: Юлий Тарасов.
Предыдущий семинар: • Практика языка C (МФТИ...
Следующий семинар: • Практика языка C (МФТИ...
Слайды к занятиям: cs.mipt.ru/wp/?page_id=7775
Примеры кода: github.com/tilir/c-graduate
Задачник: olymp1.vdi.mipt.ru/
Timeline
00:00 Intro
02:26 Genesis
09:35 Пространственные соотношения
22:30 Указатели на указатели
28:42 Массивы
33:30 Виртуальная память
37:28 Структура адресного пространства
45:10 Время решать задачи
48:47 Время жизни и область видимости
51:20 Куча и утечки памяти
58:40 Исчерпание кучи и исчерпание стека
01:06:47 Статические переменные
01:11:30 Бенчмаркинг
01:21:10 Литература и завершение
Errata:
* пока пусто

Опубликовано:

 

13 июл 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 66   
@user-td8wl7dd4m
@user-td8wl7dd4m 8 месяцев назад
Как же повезло этим ребятам
@dmitrii-329d
@dmitrii-329d 8 месяцев назад
За этим везением стоит много труда
@tilir
@tilir 8 месяцев назад
Кстати в этом году действительно речь идёт о чистом везении (ну или невезении как посмотреть). На меня видимо за что-то обиделся ответственный за распределение (я не разбирался) и мне выдали не ребят и девушек которые лучше прочих написали распределительный контест, а просто кого-то из середины списка результатов. Мне в общем всё равно с кем работать, они все физтехи. Но факт в том, что в этом году, как и в старые добрые времена, чтобы попасть ко мне, нужно было написать входное распределительное тестирование по информатике ПЛОХО, а не хорошо. Но никто не знал заранее насколько именно плохо, в чём и была интрига )))
@user-td8wl7dd4m
@user-td8wl7dd4m 8 месяцев назад
Продолжайте и дальше выкладывать материал, Вас смотрят со всех мест нашей необъятной!
@alex_s_ciframi
@alex_s_ciframi 7 месяцев назад
@@tilir неважно, откуда выборка. Жемчужина может проснуться/обнаружиться где угодно :) Может, какой-нибудь ученик и не знает, что в нём спит талант, а тут раз - опачки )
@user-wh3to1fn3c
@user-wh3to1fn3c 8 месяцев назад
Владимир, низкий Вам поклон за лекции. Это действительно качественный материал, с удовольствием смотрю все лекции. На работе давно пишу на Си, но там не менее нахожу для себя всегда что-то новое в Ваших записях
@tilir
@tilir 8 месяцев назад
Спасибо на добром слове. Только я Константин ))
@evgeniykochetkov2702
@evgeniykochetkov2702 8 месяцев назад
я пришел немного подушнить и сказать, что 90210 это почтовый индекс в беверли хилсс) Отличня лекция! Смотрю с удовольствием и интересом!
@user-rz6oy9fc4l
@user-rz6oy9fc4l 8 месяцев назад
Если бы я учился в этом ВУЗе я б не вылазил бы с лекций Константина
@tilir
@tilir 8 месяцев назад
Я иногда шучу что мои лекции очень любят все, кроме тех, кто должен на них ходить ))
@my_learning_spaceship
@my_learning_spaceship 2 месяца назад
​@@tilir если бы у моих преподавателей были бы записи с хотя бы в четверть с таким звуком, я бы с радостью смотрела бы их так же на двойной скорости и кайфовала бы с лекций, а не засыпала бы, когда чуть переставала догонять
@DART2WADER
@DART2WADER 8 месяцев назад
11:07 в ядрах ARM есть механизм bit banding для линейной адресации по битам. В основном это сделано для быстрого управления регистрами переферии.
@ivankorotkov2563
@ivankorotkov2563 8 месяцев назад
26:10 можно смотреть на указатели и числа как на точки и вектора в одномерном пространстве. Мы можем сложить два вектора (два числа)? - да, получим вектор (число). Можем сложить две точки (адреса) - нет. Можем вычесть две точки (адреса) друг из друга - да, получим вектор (число). Чтобы лучше это представить, можно представлять точки и вектора одномерного пространства как элекменты двухмерного пространства (x, y), где x - координата точки или вектора, а y может принимать только значения 0 или 1. Где 0 означает что элемент является вектором, а 1 - точкой. Вылетело из головы как такое представление называется.
@tilir
@tilir 8 месяцев назад
Интересное рассуждение. Но чисто интуитивно вектор (радиус-вектор) это скорее указатель =)
@ivankorotkov2563
@ivankorotkov2563 8 месяцев назад
@@tilir Я смотрю на эту аналогию так: есть векторное пространство адресов в памяти. Точка на нем - конкретный адрес. Вектор - это офсет на который этот адрес можно сдвинуть.
@alexandrsmirnov8615
@alexandrsmirnov8615 8 месяцев назад
49:34 Почему получили SIGSEGV, а не печать мусорного значения? Адрес "res" располагался на стеке, который заранее выделен для этого процесса и размер этого стека фиксирован. Т.е. вроде бы обращаемся к памяти, которая выделена под наше приложение и существует пока программа запущена.
@tilir
@tilir 8 месяцев назад
Мы научимся отвечать на такие вопросы во второй части курса, когда научимся смотреть дизассемблер ))
@jonnyradars
@jonnyradars 5 месяцев назад
@@tilir а вы вторую часть выложите в этот же плейлист? если нет, то где её можно будет найти?
@sergeykirdyankin7027
@sergeykirdyankin7027 8 месяцев назад
Неинициализированный глобальный массив попадёт в .bss и как следствие на размер бинарника не повлияет, а занулен будет (весь bss) чем то вроде memset. В секцию .data попадут только глобальные переменные с начальными значениями и они уже будут помещены в бинарник (иначе откуда эти начальные значения брать)
@ПЛИСоводство
@ПЛИСоводство 3 месяца назад
Грамотный преподаватель и отличные лекции. В своё время мне тоже с преподавателем повезло. Возник вопрос, как бороться с фрагментацией кучи, если это вообще возможно? И есть ли какой-то способ принудительно освободить всю кучу сразу?
@niceday1713
@niceday1713 4 месяца назад
Добрый день, замечательная лекция! У меня вопрос, хотел именно для себя прояснить: а на 16 слайде у вас нет "неточности" на картинке? Просто там показано, что процесс 1 ссылается на адрес на диске, но если я все правильно понимаю, он должен ссылаться на оперативную память, а та, в свою очередь, на жесткий диск (сначала ищем значение в кэше, потом в оперативке, потом уже на диске)? Поправьте, пожалуйста, если я неправильно понимаю.
@tilir
@tilir 4 месяца назад
Там стрелка идёт через операционку и мы предполагаем что всё о чём вы говорите она берёт на себя.
@user-qr4xq9fd6t
@user-qr4xq9fd6t 8 месяцев назад
И переменная и ее адрес и адрес ее адреса (при условии, что все сохранили) - это все какие-то биты в памяти. Правильно ли, что "указатель" это, своего рода, договоренность (контракт), в языке между компилятором и программистом? Когда программист заводит переменную типа указатель, то компилятор при работе с этой переменной, использует правила этого контракта.
@tilir
@tilir 8 месяцев назад
Адрес это не обязательно биты в памяти. Может быть переменная у которой адрес не материализован в память. Он тем не менее у неё есть. Что до контракта так любой тип это контракт. Собственно это часть определения object type: это коробочка value type + набор операций.
@artemosipuk5731
@artemosipuk5731 8 месяцев назад
К семинару остались вопросы. Нет сложностей для того, чтобы адресное пространство кучи и стека одной программы двигались друг на встречу другу. Но как это реализовано для нескольких программ?
@tilir
@tilir 8 месяцев назад
Для каждого процесса своя виртуальная память.
@user-tx1rp8pm7x
@user-tx1rp8pm7x 2 месяца назад
Здравствуйте, Константин 1:07:54 (static int i = 0;) про глобальную переменную с ограниченной областью видимости понятно. а что с инициализацией? почему = 0 каждый раз не отрабатывает при вызове функции? или инициализация компилятором куда-то выносится? а что если там вызов функции? static int i = getValue();
@tilir
@tilir 2 месяца назад
Инициализируется единожды при первом заходе в функцию.
@nullptr_or_null8301
@nullptr_or_null8301 Месяц назад
"почему = 0 каждый раз не отрабатывает при вызове функции" - static говорит компилятору что как правильно сказано инициализируется единожды при первом заходе в функцию, но храниться это переменная и ее значение и ее адрес все время работы программы, но видимость этой переменной только будет в функции, а не во внешнем или внутренним связыванием в файле, поэтому значение будет храниться все время работы программы.
@DART2WADER
@DART2WADER 8 месяцев назад
28:31 а вас я попрошу остаться)) Можете вкратце пояснить за с++.
@tilir
@tilir 8 месяцев назад
Форма 2[x] не будет работать при перегрузке op[].
@tohoto2183
@tohoto2183 4 месяца назад
Уважаемый Константин ,а почему в место глобальных переменных не использовать enum{} ?
@tilir
@tilir 4 месяца назад
При таких комментариях оставляйте пожалуйста таймкод какое место вы имели в виду. Или номер слайда.
@tohoto2183
@tohoto2183 4 месяца назад
@@tilir Это не вопрос по видео, это вопрос вообще . Через enum очень удобно вводить глобальные переменные и их не изменить.
@tilir
@tilir 4 месяца назад
@@tohoto2183это называется глобальные константы. Да удобно но на ранних этапах не критично. Мы его разбираем на семинаре 5.2
@v.b.1544
@v.b.1544 8 месяцев назад
Здравствуйте, Константин Игоревич. Ссылка на слайды перестала работать (ошибка 404) для не студентов или она и не должна была?)
@tilir
@tilir 8 месяцев назад
Нет, должно быть всем доступно. Должно быть временные проблемы. Проверьте ещё раз.
@v.b.1544
@v.b.1544 8 месяцев назад
Ссылки работают, если вручную https поменять на http. О, вижу и в описании поправили. Или мне всё это показалось??)
@user-wv8lb7ow6k
@user-wv8lb7ow6k 8 месяцев назад
Вы сказали что static можно считать как глобальную, а на деле она передается каждый раз через стек как то автоматически?
@tilir
@tilir 8 месяцев назад
Нет, на деле она и есть глобальная.
@user-wv8lb7ow6k
@user-wv8lb7ow6k 8 месяцев назад
@@tilir Спасибо за видео, на многие вопросы ваши отвечал(по типу что Null имеет тип void*), хотя я не программист и только сайт метанит прочитал, очень интересно слушать и понимать
@stanislavstanislavius7618
@stanislavstanislavius7618 8 месяцев назад
Если адрес - это расстояние от начала памяти, до переменной, то получается, что длина памяти в 64 битной системе не может превышать 8 байт?
@tilir
@tilir 8 месяцев назад
2 в 64 степени байт.
@stanislavstanislavius7618
@stanislavstanislavius7618 8 месяцев назад
@@tilir еще более непонятно стало(
@v.b.1544
@v.b.1544 8 месяцев назад
В 64 битной системе адрес байта кодируется числом из 64 бит. А это 2^64 адресов: от 0 до 2^64 - 1.
@andrey7530
@andrey7530 8 месяцев назад
вроде верно, что если указатель 8 байт, выделяемые 64битной системой под него , то у него 8[байт] * 8[бит/байт]=64 бит
@vad1mse688
@vad1mse688 21 день назад
Константин, верно ли я понимаю, что (px - py) будет UB? Если int x, y; int *px = &x; int *py = &y;
@tilir
@tilir День назад
Да это UB, но на этом семинаре дети ещё не знают такого слова.
@vad1mse688
@vad1mse688 День назад
@@tilir Спасибо.
@vad1mse688
@vad1mse688 21 день назад
Есть ли возможность получить задачи из задачника?
@tilir
@tilir 21 день назад
В каком смысле? Исходники?
@vad1mse688
@vad1mse688 День назад
@@tilir сам текст задач. К сожалению, на сайте не могу зарегистрироваться.
@tilir
@tilir День назад
github.com/tilir/c-graduate/tree/master/coursework/contests
@evgenyrozhnowsky6572
@evgenyrozhnowsky6572 8 месяцев назад
40:58 по-моему так не работает)
@tilir
@tilir 8 месяцев назад
Очень легко проверяется. Сделайте глобальный массивчик на 100к элементов, заполните его чем-нибудь в инициализаторе, чтобы компилятор не снёс в bss (любые три первых элемента хватит), используйте его во внешней функции, скомпилируйте, посмотрите размер файла.
@evgenyrozhnowsky6572
@evgenyrozhnowsky6572 8 месяцев назад
@@tilir вы правы) спасибо за разъяснение, видимо мой Cl выдрал его на стадии оптимизации)
@vad1mse688
@vad1mse688 23 дня назад
20:45 Почему pb не будет ячейкой в которой будет лежать значение, если там будет адрес на нулевой элемент массива? Никак не могу понять или понимаю Ваши слова не верно.
@tilir
@tilir День назад
Потому что массив это не ячейка с адресом. Массив приводится неявно к адресу на свой нулевой элемент, но нигде в памяти он его не хранит.
@vad1mse688
@vad1mse688 День назад
@@tilirТ.е. тут речь про то, что доступ к массиву pb[], мы получаем через pb, и в таком случае происходит то, что Вы описали выше. А чтобы было, как описывал я в своём вопросе, нужно использовать calloc, о чём Вы и говорите дальше в видео. Благодарю 🙏
@vad1mse688
@vad1mse688 23 дня назад
12:25 Про амер. систему нумерации домов не нашёл информации. Чаще встречается схема, по которой 90 - номер квартала, 210 - номер дома в квартале или всё вместе - почтовый индекс.
@tilir
@tilir День назад
Нашли к чему придраться.
@vad1mse688
@vad1mse688 День назад
@@tilir даже не пытался искать. Сообщаю то, о чём узнал сам.
@ddvamp
@ddvamp 23 дня назад
25:45 Значит в С нет позитивных указателей(
@tilir
@tilir День назад
Не понял ремарку ))
@ddvamp
@ddvamp День назад
@@tilir В С++ можно использовать унарный +, чтобы получить "позитивные" указатели/функции/лямбды. Можно использовать, чтобы превратить lvalue в prvalue
@tilir
@tilir День назад
Да я в курсе. Но что это могло бы значить для C где нет вывода типов?
Далее
It works! #beatbox #tiktok
00:15
Просмотров 4,7 млн
100+ Linux Things you Need to Know
12:23
Просмотров 740 тыс.