Full transcript
0:00приветствую вас друзья меня зовут сергей
0:01мы с вами продолжаем изучать язык
0:03программирования си sharp
0:04сегодня мы с вами в подробностях
0:06разберем ключевое слово мал для чего она
0:09нужно и как она вообще используется
0:11не забудьте подписаться на канал зажимах
0:13на колокольчик чтобы не пропускать новые
0:15уроки ну и непосредственно к делу
0:16разобраться с тем что же такое ключевое
0:19слово нал и для чего она используется мы
0:21можем благодаря тому что в прошлом уроке
0:23мы с вами выяснили что такое значимое и
0:26ссылочные типы и чем они отличаются
0:28так что если вы не смотрели этот урок то
0:30рекомендую посмотреть ссылку вы найдете
0:32внизу в описании основным моментом
0:35является то что ключевое слово нал либо
0:38же значение мы можем использовать
0:40только ссылочными типами но вообще то
0:42есть еще на lable типа но о них мы
0:44поговорим отдельно в отдельном уроке
0:45обратите внимание на код который у нас
0:48написано в методе момент у нас здесь
0:50объявляются различные переменные
0:52различных типов данных и в них не
0:54присваивается не какое значение среди
0:57этих переменных есть даже наш
0:59собственный класс и наша собственная
1:01структура они не содержат никакой
1:03информации и здесь они нам нужны лишь
1:05для того чтобы посмотреть как они
1:07отличаются при взаимодействии с ключевым
1:10словом на лт поставим брать помнить на
1:1149 строчки кода и просто запустим нашу
1:15программу весь код в методе main
1:16выполнился
1:17и соответственно по ходу его выполнения
1:19вот эти вот все переменные были созданы
1:21давайте посмотрим что хранится в этих
1:24переменных после того как мы их объявили
1:26напоминаю здесь важным моментом является
1:28то что мы не присваивали в них никаких
1:30данных просто объявили переменную
1:32перемен на обе типа bool у нас здесь
1:35хранится значение фолз попеременно и
1:38здесь у нас int здесь ноль переменная
1:41типа дабл ди здесь ноль рандом класс
1:45random с помощью которого мы
1:47генерировали случайные числа здесь у нас
1:49знал массив объявили но не выделяли под
1:53него место в оперативной памяти здесь
1:55также нал наш класс и наша структура
1:58обращая внимание на класс здесь нам
2:01обращая внимание на структуру минут
2:03здесь нам важно то что здесь не надо на
2:06самом деле это дефолтное значение для
2:07нашей структур
2:08давайте теперь систематизируем то что
2:10масоны и увидели если у нас объект либо
2:14же переменная которую мы с вами создали
2:16относится к классу то есть является
2:19ссылочным типом то значение которое у
2:22нее было установлено по умолчанию если
2:25мы не присваивали туда ничего другого
2:27всегда нал если же это значимый тип то
2:31есть структура то дефолтное значение
2:33зависит от того какой тип данных у этого
2:36значимого типа соответственно нам с вами
2:38нужно вспомнить какая вообще разница
2:40между структурами и классами если вы
2:43смотрели прошлый урок то вы знаете что
2:45структуры
2:47относятся к значимым типом они
2:49размещаются в стеке и соответственно
2:52когда мы работаем со структурой мы
2:54работаем непосредственно с данными вот
2:56пример с прошлого урока который
2:58иллюстрирует каким образом структура
3:00располагается в памяти
3:01но что если мы работаем с классом классы
3:04у нас являются ссылочными типами и свои
3:07данные они хранят в управляемой куча в
3:10стеке же хранится только ссылка
3:12посмотрите вот на какой момент пустим мы
3:14с вами создаем массив и мы не
3:16присваиваем в него не какое значение не
3:18выделяем под него место в памяти то есть
3:20получается в момент когда мы с вами
3:22объявили переменную ссылочного типа мы с
3:25вами на стыке разместили
3:27скажем так некий ярлык который хранит
3:29ссылку на данные которые располагаются в
3:33куче но мы с вами эти данные здесь еще
3:35не создали соответственно ярлык у нас
3:37есть а данных нет так вот нал по сути
3:40себя представляют пустую ссылку то есть
3:43ситуацию когда у нас есть переменная в
3:46которой мы должны хранить ссылку на
3:48объект в управляемой куча но реального
3:51объекта нету
3:52объекта нету ссылка есть соответственно
3:55когда мы пытаемся получить данные по
3:57этой ссылке там ничего нет и вот это вот
3:59ничего пустая ссылка отсутствие связи
4:02наши ссылки с данными в управляемой кучи
4:05это и есть нам дали из этого вполне
4:08логично выходит что раз только ссылочные
4:11типы у нас хранятся в управляемой куча
4:13то значимых типах нал хранится нему
4:16потому что они хранят свои данные прямо
4:18на стыке а у них вообще ссылки нету если
4:21мы создаем переменную значимого типа то
4:23там у нас реальные данные и так как
4:26объект у нас храниться не в куче а в
4:28стеке то тут не может быть на у потому
4:30что это у нас не ссылка
4:31реальное значение в эту переменную если
4:34мы ее просто объявляем и не помещаю туда
4:36никаких данных помещается дефолтное
4:38значение подобное поведение у нас и
4:40ссылочными типами но для всех ссылочных
4:43типов дефолтное значение то есть
4:45отсутствие ссылки на реальные данные в
4:48управляемой кучу теперь пойдем немного
4:50дальше итак мы с вами создали объект
4:53ссылочного типа данном случае это у нас
4:55массив типа int объявили переменную в
4:58стеке у нас соответственно существует
5:01ссылка на какой-то объект в куче так как
5:03реального объекта в кучу у нас нет мы не
5:05выделяли под него оперативную память у
5:07нас сейчас здесь но сделаем следующий
5:09шаг теперь мы с вами с помощью оператора
5:12new
5:13а выделяем оперативную память под наш
5:15массив так как это у нас ссылочный тип
5:18то оперативная память выделяется у нас
5:20управляемый кучек соответственно наша
5:24ссылка которая у нас хранится на стыке
5:26теперь не содержит нам она ссылается на
5:29реальные данные оператор new выделяет
5:32место в управляемой куча под наши данные
5:34и соответственно возвращает нам ссылку
5:36на эти данные которая и хранится у нас в
5:39нашей переменной эй мы можем сразу же
5:41присваивать значения при объявлении
5:43переменной как это у нас было на слайде
5:45ну либо же можем сделать это позже это
5:47несущественно
5:48давайте сейчас сделаем это позже ставим
5:51брейк-пойнт у двадцать восьмой строчке
5:52кода на двадцать шестой строчке кода у
5:54нас сейчас в переменной эй нал она
5:58двадцать восьмой строчке кода у нас
5:59вызывается оператор new который в
6:01управляемой кучу нам сейчас создаст
6:03место под наш массив и вернет ссылку на
6:05эту область в памяти в нашу переменную и
6:09как только это происходит вместо мало в
6:11отладчике мы там видим реальные данные
6:13видим что там массивно 10 элементов
6:15можем даже раскрыть и посмотреть все эти
6:18элементы мы сейчас с вами находимся вот
6:20в таком состоянии по коду но что если
6:22дальше по ходу выполнения нашей
6:24программы объекту либо же переменной в
6:27которая ссылается на наш массив
6:29управляем и куча мы присвоим на таком
6:31случае вот эта связь между нашей ссылкой
6:34которая у нас хранится в стеке
6:35реальными данными в управляемой кучи
6:38будет разорвана обратите внимание на
6:40жёлтую стрелку давайте по ходу нашей
6:46программы сделаем тоже самое запускаем
6:48вот и баги и так в нашей переменное
6:50значение нал двадцать восьмой строчке
6:52выделяем место в управляемой куча
6:54получаем ссылку но эти данные и на 30
6:58строчки кода мы опять туда присылаю wine
7:00нал мы разрываем связь между переменной
7:02эй которая у нас хранится на стейки и
7:05данными которые у нас находятся в
7:08управляемой куча переменная на стыке
7:10осталось данным управляемым куча
7:12остались на адрес который у нас хранился
7:15в этой переменной а л и который ссылался
7:18на область памяти в управляемой кучу мы
7:20потеряли
7:21если бы это были siplus и потом он бы
7:23сейчас с вами получили утечку памяти
7:25потому что мы бы заселили оперативную
7:28память и соответственно никак ее не
7:30очистили соответственно если бы мой так
7:33писали наши программы мы все больше и
7:35больше бы использовали оперативной
7:37памяти в итоге она у нас по закончилась
7:39ночь шара пьесами вот таким вот образом
7:40разрываем связь между ссылкой которая
7:43находится в стеке реальными данными
7:45которые находятся в управляемой куча ту
7:48память которая находится управляемой
7:50куча и использовалась в данном случае
7:52под наш массив в дальнейшем очистит
7:55сборщик мусора гарбич коллектор но если
7:57бы мы с вами работали не ссылочным типа
8:00масса значимым типом у нас бы всего
8:02этого вообще не происходило потому что у
8:04нас бы данные в управляемой кучи не
8:05выделялись и все хранилось бы на стыке
8:07соответственно мы туда инал бы не могли
8:09присвоить и соответственно раз никаких
8:11данных управляемой куча не было то и не
8:14было никакой необходимости в работе
8:16сборщика мусора
8:17теперь хочу показать он немного более
8:20сложный пример допустим у нас создание
8:24массива и выделение под него оперативной
8:26памяти происходит в каком-то методе в
8:29данном случае это метод фу он у нас
8:31вызывается в майне мы с вами знаем что
8:34методов ей свой собственный контекст
8:36либо же область видимости и также из
8:39прошлых
8:40уроков мы с вами знаем что переменные
8:42которые были созданы в определенном
8:43контексте
8:44их время жизни продолжается только в
8:47этом контексте
8:48если метод у нас выполнился и мы с него
8:50вышли все что было внутри этого метода
8:53у нас уже не существует если это у нас
8:56значимый тип то есть допустим какая-то
8:59переменная int алая структура то как
9:03только мы выйдем из методов у
9:05она просто удалиться из стека на что у
9:08нас произойдет со ссылочным типом ведь у
9:10нас еще есть место в управляемая куча
9:12под данные которые мы создавали давайте
9:14рассмотрим более подробно ставим
9:16брейк-пойнт на двадцать шестой строчке
9:17кода где у нас вызывается метод fun
9:19делаем шаг за ходом в этом методе у нас
9:22создается массив и
9:23и мы выделяем под него место в куче под
9:2610 элементов вот он наш массив
9:28теперь смотрите как только мы выйдем за
9:31вот эти вот фигурной скобки где у нас
9:33сейчас желтая стрелка то мы покинем
9:36контекст либо же область видимости
9:38методов у
9:39соответственно вот этот вот объект
9:41ссылочного типа по факту ссылка которая
9:43хранится у нас в стеке которая у нас
9:45и называется и которая ссылается на
9:48какую-то область в управляемой куча где
9:50у нас реальная
9:51реальная память выделено под наш массив
9:54вот эта ссылка будет удалена потому что
9:56мы покинем контекст методов
9:58что у нас будет с реальными данными
10:00делаем шаг мы покинули метод full если
10:04мы сейчас даже попытаемся в отладчике
10:05навестись на переменную и отладчик уже
10:08никак не реагирует у нас уже нету этой
10:10переменной даже вот еще сделан шаг мыши
10:12127 строчки кода метод фу у нас уже
10:14отработал по факту мы получаем вот такую
10:17ситуацию переменной r значение которое у
10:19нас хранилось ссылку на данный
10:21управляемой кучу у нас его уже просто
10:23нету но вышли из контекста
10:24соответственно все что было в том
10:25контексте со стока удалено у нас нету
10:27ссылки
10:28а данный в управляемой куча остались вы
10:30соответственно я уже думаю вы понимаете
10:32что с этими данными должно что-то
10:34произойти и эти данные будут очищены
10:36удалены из управляемой кучи с помощью
10:38сборщиком мусора но опять-таки если бы
10:41это у нас были все плюсы и мы не
10:43позаботились о самостоятельной очистки
10:45памяти мы бы получили утечку памяти нота
10:47си sharp
10:48поэтому здесь нам об этом беспокоиться
10:50не нужно
10:51это кстати можно отнести к одному из
10:53достоинств языка программирования си
10:55sharp потому что разработчик может
10:57сосредоточиться непосредственно на
10:59разработке программы а не на том чтобы
11:00не получить где-то утечку памяти
11:03ну и теперь ещё один важный момент с
11:05которым очень часто сталкиваются новички
11:07исключения на лари френдс exception то
11:09есть ошибка выполнения программы
11:11вот такая например да и обработано
11:14исключение системного reference
11:16exception ссылка на объект не указывает
11:17на экземпляр объекта просто посмотрим в
11:20баке на двадцать первой строчке кода мы
11:22сами создаем массив сразу же выделяем
11:24под него место управляемой кончено
11:25двадцать третьей строчке кода мы
11:27присваиваем тут она соответственно
11:28объект который у нас находится в стеке
11:30не ссылаются никуда управляемую кучу на
11:33какие-то данные
11:34но двадцать пятой строчке кода мы у
11:37этого массива у этого объекта в стеке
11:39пытаемся извлечь индекс массива
11:43то есть говорим ему а поди-ка куда-то в
11:45управляемую кучу найди там данные
11:47которые там лежат и и возьми мама эти
11:50данные под индексом ноль и выведи их на
11:52консоль что может сделать если у него
11:56нету адреса куда идти потому что там
11:58сейчас нал и соответственно ссылки нету
12:00программа пытается это сделать пытается
12:03извлечь
12:03индекс 0 из ничего и соответственно мы
12:06получаем нал reference exception ну это
12:09и логично потому что ссылка которая у
12:11нас есть то есть имя нашего массива
12:13у нее просто не было адреса на реальные
12:16данные на реальных экземпляра
12:17управляемой куч соответственно если вы
12:19видите подобное исключение это означает
12:21что вы где-то потеряли данные ну либо же
12:25просто не создали массивнее присвоили
12:27что-то куда-то и соответственно я думаю
12:28вам теперь будет понятно почему
12:29происходит подобное исключение если вам
12:32понравился данный урок не забудьте
12:34поставить лайк под этим видео если у вас
12:36есть желание поддержать меня и канал
12:37финансовой информации о том как это
12:39сделать найдете внизу в описании буду
12:40рад все по делитесь уроком с друзьями
12:42мной конечно если вы ещё не подписались
12:44на канал то обязательно подписывайтесь
12:46здесь уже есть и будет очень много
12:47полезных интересных уроков для вас всем
12:49спасибо за внимание пока