[Грає музика]
>> ДАГ 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.