[Играет музыка] ДАГ Lloyd: Хорошо, таким образом предложение перед началом здесь. Если вы не смотрели видео на указатели вы можете сделать так в первую очередь. Потому что это видео является еще одним способ работы с указателями. Таким образом, это будет говорить о некоторых понятий что мы рассмотрим в Указатели видео, и мы собирается замалчивать их сейчас, предполагая, что они уже вроде понял. Так что это просто ваш справедливое предупреждение что если вы видите это видео и вы еще не видели указатели видео, это могло бы своего рода летать над вашей головой немного. И так было бы лучше чтобы посмотреть его в таком порядке. Таким образом, мы уже видели один способ работы с указателями, что мы объявить Переменная, а затем мы объявить еще одну переменную, указатель Переменная, которая указывает на него. Таким образом, мы создали Переменная с именем, мы создал вторую переменную с именем, и мы указываем, что вторая переменная на что в первую очередь. Этот вид имеет Проблема, хотя, потому что это требует от нас, чтобы точно знать, сколько памяти мы понадобится в тот момент, наша программа будет скомпилирована. Почему это? Потому что мы должны быть в состоянии назвать или определить все возможные переменные мы могли бы столкнуться. Мы могли бы иметь массив, что может быть в состоянии держать много информации, но это еще не точно достаточно точным. Что делать, если мы не знаем, что, если у нас нет ни малейшего представления сколько нам нужно во время компиляции? Или что, если наша программа будет запустить в течение действительно долгого времени, принимая различные пользователя данных и мы не можем на самом деле оценить ли мы понадобится 1000 единиц? Это не то, мы можем говорят в командной строке введите сколько предметов Вы думаете, что вы будете нуждаться. Ну что, если это предположение неверно? Динамическое выделение памяти рода позволяет нам путь чтобы обойти этой конкретной проблемы. И то, как он это делает является использование указателей. Мы можем использовать указатели на получить доступ к динамически выделенная память, память, выделено в качестве программы. Это не выделяется во время компиляции. Когда вы динамически выделять памяти она исходит от бассейна памяти известен как кучи. Ранее все мы в памяти работает с в ходе был исходя из пула памяти известен как стек. Хороший способ, как правило держать в mind-- и из этого правила не всегда справедливы, но в значительной степени почти всегда держит true--, что любой раз вы дать имя переменной его вероятно, живет в стеке. И в любое время вы не дать переменной имя, которые вы можете сделать с динамической памятью распределение, она живет в куче. Теперь я вроде представления, как это если есть эти два бассейна памяти. Но вы, возможно, видели это Диаграмма, которая, как правило представление то, что память выглядит, и мы не собираемся, чтобы заботиться обо всем материал в верхней и нижней части. То, что мы заботимся о том, эта часть в средний здесь, куча и стек. Как вы можете видеть, глядя на эту диаграмму, это на самом деле не два отдельные бассейны памяти. Это одна общая пул памяти где вы начинаете в это визуальная Вы начинаете в нижней и начать заполнение со дна стека, и вы начать в верхней и начать заполнение сверху вниз с кучи. Но на самом деле это тот же пул, это просто различные пятна, разных местах в памяти, которые выделяются. И вы можете работать из памяти, либо имеющие куча пройти весь путь на дно, или стек пройти весь путь к вершине, или имеющие кучу и стек встретиться друг с другом. Все те, может быть условия которые вызывают вашу программу бежать из памяти. Так что имейте это в виду. Когда мы говорим о куча и стек мы на самом деле говорим о Вообще же кусок памяти, просто различные части этой памяти. Так как же нам получить динамически распределенной памяти в первую очередь? Как получить нашу программу памяти, как он работает? Ну С предусмотрена функция таНос, память распределитель, который Вы делаете вызов, и вы проходите в сколько байт памяти, которые вы хотите. Так что, если ваша программа работает и вы хотите целое выполнения, Вы могли бы Mallock четыре байта памяти, таНос скобки четыре. Mallock будет пройти глядя через кучу, потому что мы динамически выделения памяти, и он вернется к вам указатель на эту память. Это не дает вам, что memory-- это не дает ему имя, это дает вам указатель на него. И вот почему я снова сказал что важно, может быть, просмотрели видео указатели прежде чем мы получим слишком далеко в этом. Так таНос собирается дать вам обратно указатель. Если Mallock не могу дать вам какой-либо памяти, потому что вы запустите из, это даст Вам нулевой указатель. Вы помните, что произойдет, если мы попытаться разыменования нулевого указателя? Мы страдаем неисправность SEG, не так ли? Это, вероятно, не очень хорошо. Таким образом, каждый раз, когда вы сделать звонок чтобы таНос вас всегда, всегда необходимо проверить, является ли указатель он дал вам обратно пустым. Если это так, вы должны закончить вашу программу потому что, если вы попробуете и разыменования нулевой указатель вы собираетесь страдать ошибку сегментации и ваша программа врежется в любом случае. Так, как мы статически получить целое число? INT х. Мы, вероятно, сделали что кучу раз, верно? Это создает переменную с именем х, который живет в стеке. Как мы динамически получаем число? Int звезда ПВ равна таНос 4. Или более уместно мы бы сказали, INT звезд точек равна выделения памяти размер Int, просто бросить некоторые меньше магические числа вокруг нашей программы. Это будет для нас получить четыре байта памяти из кучи, и указатель мы получаем вернуться к ней называется пикс. А потом просто, как мы сделано ранее мы может разыменовать пикселей на доступ к этой памяти. Как мы можем получить целое число от пользователя? Мы можем сказать, INT х равен получить Int. Это довольно просто. Что делать, если мы хотим создать массив х поплавков, которые живут в стеке? плавать stack_array-- это имя наших array-- квадратных скобках х. Это создаст для нас массив х поплавков, которые живут в стеке. Мы можем создать массив поплавков что живет в куче, тоже. Синтаксис может выглядеть немного более громоздким, но мы можем сказать, поплавок звездочный heap_array равна таНос х раз размер поплавка. Мне нужно достаточно места, чтобы провести х с плавающей запятой. Так сказать, мне нужно 100 поплавки, или 1000 поплавки. Так что в этом случае было бы 400 байт на 100 поплавков, или 4000 байт на 1000 поплавков, потому что каждый поплавок занимает четыре байта пространства. После этого я могу использовать квадрат синтаксис кронштейн heap_array. Так же, как я бы на stack_array, я может получить доступ к его элементы по отдельности используя heap_array нулю, heap_array одним. Но вспомнить причину мы можем сделать, что это потому, что имя массива в C действительно указатель на Первый элемент этого массива. Так на то, что мы объявлении массив плавает в стеке здесь на самом деле немного вводит в заблуждение. Мы действительно в Вторая строка кода есть Также создание указатель на кусок памяти, что мы тогда делать какую-то работу с. Вот большая проблема с динамической памятью, хотя, и именно поэтому это действительно Важно разработать некоторые хорошие привычки когда вы работаете с ним. В отличие от статически объявлена памяти, ваша память автоматически не возвращается в Система, когда ваша функция сделать. Так что, если у нас есть главный, и Основной вызывает функцию е, когда F отделки все, что делает и возвращает управление программой на главную, вся память что F используется дается назад. Он может быть использован снова другой программой, или некоторые другие функции, которые вызывается позже в основном. Он может использовать эту же память снова и снова. Если вы динамически выделить память, хотя Вы должны явно указать Система, что вы сделали с ним. Это будет держать на него для вас, которые могли бы привести к проблеме из вас уходит памяти. И в самом деле, мы иногда называем на это как утечка памяти. И иногда эти утечки памяти может на самом деле быть действительно разрушительным для производительности системы. Если вы часто интернет-пользователь Вы могли бы использовать некоторые веб-браузеры, и я не буду называть имен здесь, но Есть некоторые веб-браузеры там что печально известны фактически не имея утечки памяти, которые не получают фиксированные. И если вы выходите ваш браузер с открытым для очень долгого периода времени, дней и дней, или недель, иногда Можно заметить, что в вашей системе это работает на самом деле, очень медленно. И причина для этого является то, что браузер выделил память, но тогда не сообщил систему что это сделано с ним. И так, что оставляет меньше памяти доступны для всех ваших других программ чтобы поделиться, потому что вы leaking-- что веб-браузер Программа утечка памяти. Как мы даем память назад когда мы сделали с ним? Ну, к счастью, это очень простой способ сделать это. Мы просто освободить его. Там это функция называется свободным, он принимает указатель на память, и мы хорошо идти. Итак, давайте говорить, что мы в середина нашей программы, мы хотим, чтобы таНос 50 символов. Мы хотим, чтобы таНос массив, который может способна удерживать 50 символов. И когда мы получаем указатель обратно что имя этого указателя является слово. Мы делаем все, что мы собирается делать со словом, а затем, когда мы сделано, мы просто освободить его. А теперь мы вернулись те 50 байт памяти обратно в систему. Некоторые другие функции могут их использовать. Мы не должны беспокоиться о перенося утечка памяти, потому что мы освободили слово. Мы дали память назад, так, что мы закончили работать с ним. Таким образом, есть три Золотые правила, которые должны иметь в виду, когда вы динамического распределения памяти с таНос. Каждый блок памяти, Вы таНос должны быть освобождены Перед вашей программы завершения работы. Теперь снова, в устройстве или в IDE такого рода происходит для вас в любом случае когда you-- это произойдет в любом случае если ваша программа завершается, вся память будет выпущен. Но это в целом хороший кодирование Практика всегда, когда вы закончите, освободить то, что вы mallocd. Это сказало, только то, что Вы имеете mallocd должны быть освобождены. Если вы статически провозгласить число, INT х запятой, что живет в стеке, вы не то хочу, чтобы освободить х. Так только то, что вы mallocd должны быть освобождены. И, наконец, не бесплатно что-то в два раза. Это может привести к другой странная ситуация. Так что все, что вы имеете mallocd должен быть освобожден. Только то, что вы таНос должны быть освобождены. И не бесплатно что-то в два раза. Итак, давайте рассмотрим пример здесь что некоторые динамически распределяется памяти может выглядеть смешанной в с некоторой статической памяти. Что может случиться здесь? Смотрите, если вы можете следовать вдоль и думаю, что произойдет, как мы идем все эти строк кода. Поэтому мы говорим, INT м. Что здесь происходит? Ну это довольно просто. Я создаю целое переменную м. Я покрасить его зеленым, потому что это цвет что я использую, когда я говорю о целочисленные переменные. Это коробка. Это называется м, и вы можете магазин целые внутри него. Что делать, если я тогда сказать INT звезде? Ну, что это довольно похожи. Я создаю окно называется. Он способен холдинга Int звезды, указатели на целые числа. Так что я окраски это зеленый-иш, а также. Я знаю, что есть что-то сделать с целым числом, но это само по себе не является целым числом. Но это в значительной степени та же идея. Я создал окно. Оба эти права в настоящее время живут в стеке. Я дал им имена обоих. INT звезда б равна выделения памяти размер Int. Этот может быть немного сложнее. Возьмите второй и подумайте, что вы было бы ожидать, чтобы это произошло на этой диаграмме. INT звезда б равна выделения памяти размер Int. Ну это не просто создать одну коробку. Это на самом деле создает две коробки. И это привязывает, он также устанавливает точка в отношениях. Мы выделено один блок памяти в куче. Обратите внимание, что верхний правый ящик есть не есть имя. Мы mallocd его. Она существует на куче. Но Ь имеет имя. Это переменная указатель называется б. Это живет в стеке. Так что это часть памяти что указывает на другой. б содержит адрес этого блока памяти. Это не есть имя иначе. Но он указывает на него. Поэтому когда мы говорим INT звезда б равна Размер таНос ИНТ, что тут, что стрелка, которая выскочил на правая сторона есть, что вся вещь, Я он появится опять же, то, что происходит. Все, что происходит в что одна строка кода. Теперь мы получим немного больше просто еще раз. А равно амперсанд м. Помнишь вам, что равна амперсанд м есть? Ну, это получает адрес M'S. Или, более схематично, а указывает на м. А равно б. ИТАК, вот еще один. А равно б. Что должно случиться диаграмме это время? Ну напомнить, что Оператор присваивания работы путем присвоения значения на Право на стоимости слева. Таким образом, вместо указывающего м, А теперь указывает на то же место, что б точек. а, не указывают на B, A указывает, где б баллов. Если острый б, что бы были равно амперсанд б. Но вместо этого равна б только означает, что б сейчас указывая на тот же адрес, потому что внутри б только адрес. А теперь внутри это тот же адрес. м равна 10, вероятно, Наиболее простое дело мы сделали в немного. Поместите 10 в коробке. Звезда б равна м плюс 2, напомним, из наш указатели видео, что звезда б означает. Мы собираемся разыменовывания б и положить некоторое значение в этом месте памяти. В этом случае 12. Поэтому, когда мы разыменовывать точки Напомним, мы просто двигаться вниз стрелку. Или другими словами, мы перейти на этот адрес памяти и мы манипулировать каким-то образом. Мы ставим некоторое значение в там. В этом случае звезды В равен т плюс 2 просто перейти к переменной, на которую указывает б, перейти к памяти, на которую указывает б, и положил м плюс 2 там, 12. Теперь я свободно б. Что происходит, когда я освобождаю б? Помните, что я сказал, бесплатные средства. Что я говорю, когда я освободиться б? Я сделал с ним работать, не так ли? Я по существу отказаться от памяти. Я даю его обратно в систему. Мне не нужно это больше является то, что я говорю им, ОК? Теперь, если я говорю звезде равна 11, вероятно, можно уже сказать, что что-то плохое произойдет здесь, прямо? И в самом деле, если я пробовал, что я, вероятно, будет страдать ошибку сегментации. Потому что сейчас, хотя ранее, что часть памяти было что-то, что я имел доступ к, в этой точке теперь я доступа к памяти, что не является законным для меня, чтобы получить доступ. И, как мы, вероятно, Напомним, что, когда мы получаем доступ к памяти что мы не должны трогать, это самая распространенная причина из сегментации вина. И так моя программа будет катастрофа, если я пытался сделать это. Итак, еще раз, что это хорошая идея, чтобы получить хороший практика и хорошие привычки укоренились при работе с таНос и бесплатно, так что вы не страдаете сегментации ошибки, и что вы используете Ваш выделяется динамически памяти ответственно. Я Дуг Ллойда это CS50.