[MUZYKI]
>> DOUG LLOYD: OK, więc sugestia przed rozpoczęciem tutaj.
Jeśli nie oglądałem film na wskaźnikami możesz to zrobić w pierwszej kolejności.
Bo ten film jest inny sposób pracy ze wskaźnikami.
>> Więc to będzie mówić o niektórych pojęć
które obejmują w wskaźnikami wideo, a my jesteśmy
będzie połysk przez nich teraz, przy założeniu, że są już
rodzaj rozumieć.
Więc to jest tylko twój uczciwe ostrzeżenie że jeśli widzisz ten film
i nie widziałem wskaźniki film, to może coś w rodzaju
latać nad głową trochę.
I tak może być lepiej aby obejrzeć go w tej kolejności.
>> Więc już widzieliśmy jednego sposób pracy ze wskaźnikami,
co deklarujemy zmienna, a następnie
Oświadczam, innej zmiennej, wskaźnik zmienny, który wskazuje na to.
Więc stworzyliśmy zmienna o nazwie, mamy
utworzył drugą zmienną o nazwie i wskazać, że druga zmienna
na tym pierwszym.
Ten rodzaj ma Problem jednak, bo to
wymaga od nas, aby dokładnie wiedzieć, ile pamięci jesteśmy
będzie potrzebował moment nasz program jest skompilowany.
>> Dlaczego?
Bo musimy być w stanie wymienić lub zidentyfikowania wszystkich możliwych zmiennych
możemy spotkać.
Możemy mieć tablicę, która może być w stanie utrzymać wiele informacji,
ale to nie jest jeszcze dokładnie tyle precyzyjne.
Co zrobić, jeśli nie wiemy, co jeśli nie mamy pojęcia
ile będziemy potrzebować w czasie kompilacji?
Albo co jeśli nasz program trwać naprawdę długo,
przyjmując różne użytkownika danych, a tak naprawdę nie możemy
Szacujemy, czy jesteśmy będzie potrzebował 1000 jednostek?
>> To nie tak, możemy powiedzieć, w wierszu poleceń
wprowadzić jak najwięcej przedmiotów myślisz, że musisz.
No i co, czy to przypuszczenie jest nie tak?
Dynamiczna alokacja pamięci rodzaj pozwala nam drogę
obejść tego konkretnego problemu.
A sposób, w jaki to robi Jest przy użyciu wskaźników.
>> Możemy wykorzystać wskaźniki do uzyskać dostęp do dynamicznie
przydzielone pamięci, pamięci, która jest przydzielone w programie jest uruchomiony.
To nie jest przydzielony w czasie kompilacji.
Kiedy dynamicznie przydzielać Pamięć pochodzi z basenu
znane jako pamięci na stercie.
Wcześniej cała pamięć mamy Pracuję z w toku
przyjeżdża z puli pamięci zwany stos.
Dobrym sposobem na ogół należy mind-- i tej zasady
nie zawsze są prawdziwe, ale prawie prawie
Zawsze trzyma true-- jest, że każdy Czas podać nazwę zmiennej it
Prawdopodobnie mieszka na stosie.
I za każdym razem tego nie zrobisz dać zmiennej nazwę,
które można zrobić z pamięci dynamicznej alokacji, żyje na stercie.
>> Teraz jestem trochę prezentuje to jako jeśli jest te dwie pule pamięci.
Ale może widzieliście to schemat, który jest na ogół
reprezentacją co Pamięć wygląda,
a my nie będziemy dbać o wszystko rzeczy na górze i na dole.
Co dbamy o to ta część w środkowa tutaj, sterty i stosu.
Jak widać przez patrząc na tym schemacie,
Nie są one w rzeczywistości dwa oddzielne pule pamięci.
To jedna wspólna pula pamięci gdzie zacząć, w tym wizualne
rozpocząć na dole i zacząć zapełniać
od dołu stosu, a ty rozpoczyna się na górze i rozpocząć tankowanie
z góry na dół z hałdy.
Ale to naprawdę jest sam basen, to tylko
różne miejsca, różne lokalizacje w pamięci, które są przydzielane.
A może zabraknie pamięci, albo o
sterta przejść całą drogę na dno, lub
stos przejść całą drogę na górę, lub o sterty i stosu
spotkać się ze sobą.
Wszystkie te mogą być warunki które powodują swój program
zabraknie pamięci.
Miejcie to na uwadze.
Kiedy mówimy o sterta i stos
tak naprawdę mówimy o sam ogólny fragment pamięci, po prostu
różne części tej pamięci.
>> Jak więc się dynamicznie przydzielona pamięć, w pierwszej kolejności?
Jak działa nasz program się pamięci, jak to działa?
Cóż C zapewnia funkcję o nazwie malloc, przydzielania pamięci, które
można nawiązać połączenie, i przechodzą w jak wiele bajtów pamięci, które chcesz.
Więc, gdy Twój program jest uruchomiony i chcesz, aby czas pracy całkowitą,
możesz Mallock cztery bajty Pamięć, malloc nawiasach cztery.
>> Mallock przejdzie patrząc przez hałdy,
bo jesteśmy dynamicznie przydzielania pamięci,
i wróci do Ciebie wskaźnik do tej pamięci.
To nie daje ci tego memory-- nie daje mu nazwę,
to daje wskaźnik do niego.
A więc dlatego znów powiedziałem że ważne jest, aby być może
oglądałem film wskaźniki zanim się zbyt daleko do tego.
Więc malloc będzie oddać wskaźnik.
>> Jeśli Mallock nie daje żadnej Pamięć dlatego, że zabrakło,
będzie to oddać pustego wskaźnika.
Pamiętasz, co się stanie, jeśli spróbować dereference wskaźnikiem NULL?
Cierpimy usterki seg, prawda?
To chyba nie jest dobry.
>> Dlatego za każdym razem, kiedy nawiązać połączenie malloc Cię zawsze, zawsze
należy sprawdzić, czy wyżeł dał kopii jest zerowy.
Jeśli tak jest, trzeba zakończyć swój program bo jeśli spróbujesz i dereference
null pointer idziesz cierpieć błąd segmentacji
i Twój program jest będzie tak upaść.
Jak więc statycznie uzyskać liczbę całkowitą?
>> int x.
Mamy prawdopodobnie zrobisz kilka razy, prawda?
To tworzy zmienną x, że mieszka na stosie.
W jaki sposób możemy dynamicznie uzyskać liczbę całkowitą?
Int gwiazda px równa malloc 4.
>> Lub więcej odpowiednio powiedzielibyśmy int gwiazda px
równa malloc rozmiar int, po prostu wyrzucić niektóre mniej
Magiczne liczby wokół naszego programu.
To będzie dla nas, aby uzyskać cztery bajty pamięci ze sterty,
i wskaźnik mamy Wróć do niego jest nazywany px.
A potem, tak jak mamy zrobione wcześniej mamy
może dereference px do dostępu do tej pamięci.
W jaki sposób możemy uzyskać liczbę całkowitą od użytkownika?
Można powiedzieć, int x równa się int.
To całkiem proste.
Co zrobić, jeśli chcemy stworzyć tablicę od x pływaków, które żyją na stosie?
unosić stack_array-- to nazwa naszych array-- nawiasach kwadratowych x.
To stworzy dla nas tablicy od x pływaków, które żyją na stosie.
Możemy stworzyć tablicę pływaków który żyje na stercie, też.
Składnia może wyglądać trochę bardziej kłopotliwe,
ale można powiedzieć, pływak gwiazda heap_array równa
malloc x razy większy od pływaka.
Muszę wystarczająco dużo miejsca do przechowywania x zmiennoprzecinkowych.
Więc muszę powiedzieć, 100 pływaki lub 1000 pływaki.
A więc w tym przypadku byłoby 400 bajtów do 100 pływaków,
lub 4000 bajtów do 1000 pływaków, ponieważ każdy pływak zajmuje
cztery bajty przestrzeni.
>> Po wykonaniu tej czynności można używać nawias kwadratowy składni na heap_array.
Tak jak bym na stack_array, ja mogą uzyskać dostęp do jej elementów oddzielnie
za pomocą heap_array zero, heap_array jeden.
Ale przypominam powód możemy to zrobić Jest tak, ponieważ nazwa tablicy w C
jest naprawdę wskaźnik do Pierwszy element tej tablicy jest.
Tak więc fakt, że jesteśmy uznającej Tablica pływaków na stosie tutaj
w rzeczywistości jest nieco mylące.
Naprawdę są w Druga linia kodu nie
także tworzenie wskaźnik do kawałka pamięci, które następnie popracować z.
>> Tu jest duży problem z dynamicznie przydzielana pamięć choć,
i to dlatego, że to naprawdę ważne, aby rozwijać dobre nawyki
podczas pracy z nim.
W przeciwieństwie statycznie oświadczył pamięć, pamięć
nie jest automatycznie zwracana do System, gdy funkcja jest wykonywana.
Więc jeśli mamy głównym i Głównym wywołuje funkcję
f, gdy f wykończeń cokolwiek to robi i zwraca sterowanie programem
powrotem do głównego wszystkie pamięci że f jest stosowany zwrócona.
Może on być ponownie wykorzystywany za pośrednictwem innego programu,
lub inną funkcją jest wywoływana później w głównym.
Można go użyć tej samej pamięci na nowo.
>> Jeśli dynamicznie przydzielić pamięci choć
trzeba wyraźnie powiedzieć System, że jesteś z nim zrobić.
To będzie trzymać się go dla Ciebie, które mogłyby prowadzić do problemów z was na wyczerpaniu
pamięci.
A w rzeczywistości czasami odnoszą to jako przeciek pamięci.
I czasami te wycieki pamięci w rzeczywistości może być bardzo niszczące
na wydajność systemu.
>> Jeśli jesteś częstym użytkownikiem www można korzystać z niektórych przeglądarek internetowych,
i nie będę wymieniać nazwisk tutaj, ale istnieje kilka przeglądarek internetowych tam
które są notorycznie faktycznie konieczności wycieki pamięci, że nie dostać stałe.
A jeśli pozostawić otwartą przeglądarkę Przez bardzo długi okres czasu, dzień
i dni, lub tygodni, czasami można zauważyć, że system
jest systemem bardzo, bardzo powoli.
A powodem tego jest to, że przeglądarka przeznaczyła pamięć,
ale wtedy nie powiedział systemu że to z nim zrobić.
I tak, że pozostawia mniej pamięci dostępne dla wszystkich innych programów
aby się podzielić, bo jesteś leaking-- tego przeglądarkę internetową
Program jest wyciek pamięci.
Jak dajemy pamięć powrotem kiedy mamy z nim zrobić?
No na szczęście jest to bardzo prosty sposób to zrobić.
My po prostu uwolnić go.
Jest to funkcja zwana wolna, przyjmuje wskaźnik do pamięci,
i jesteśmy dobrze iść.
>> Więc powiedzmy, że jesteśmy w środek naszego programu,
chcemy malloc 50 znaków.
Chcemy malloc tablicę, która może w stanie utrzymać 50 znaków.
A gdy mamy wskaźnik z powrotem do że nazwa tego wskaźnika jest słowo.
Robimy co jesteśmy zamiar zrobić ze słowem,
a następnie, gdy jesteśmy odbywa się po prostu uwolnić go.
A teraz wróciliśmy te 50 bajtów pamięci z powrotem do systemu.
Niektóre inne funkcje mogą z nich korzystać.
Nie musimy martwić się o cierpienie wyciek pamięci, ponieważ uwolnił słowo.
Daliśmy pamięć z powrotem, tak skończymy pracę z nim.
Tak więc są trzy złotych zasad, które powinny
należy pamiętać, gdy jesteś dynamicznego przydzielania pamięci
z malloc.
Każdy blok pamięci Ci malloc musi zostać uwolnione
Zanim program zakończy uruchomiony.
Się ponownie w urządzeniu lub w IDE tego rodzaju dzieje się dla Ciebie tak
kiedy you-- stanie się to tak gdy program jest zakończony,
cała pamięć zostanie zwolniona.
Ale to jest na ogół dobre kodowanie Praktyka zawsze, kiedy skończysz,
uwolnić, co masz mallocd.
>> Powiedział, że tylko rzeczy, które masz mallocd powinny zostać uwolnione.
Jeśli statycznie zadeklarować całkowita, int x średnik,
że mieszka na stosie, to nie to chce uwolnić x.
Tak więc tylko rzeczy, które już mallocd powinny zostać uwolnione.
>> I wreszcie, nie wolny coś dwa razy.
To może prowadzić do kolejna dziwna sytuacja.
Więc wszystko, co masz mallocd musi być uwolniona.
Jedyne rzeczy, które zostały malloc powinny zostać uwolnione.
I nie zrobić bezpłatne coś dwa razy.
>> Więc chodźmy na przykładzie tutaj co niektóre dynamicznie przydzielane
Pamięć może wyglądać mieszane w niektóre pamięci statycznej.
Co może się zdarzyć tutaj?
Zobacz, jeśli można śledzić wzdłuż i odgadnąć, co jest
będzie się działo jak idziemy przez wszystkie te linie kodu.
>> Tak więc możemy powiedzieć, int m.
co się tutaj stało?
Więc jest to całkiem proste.
Utworzyć zmienną całkowitą o nazwie m.
I kolor to zielony, bo to kolor
że mogę używać, kiedy mówię o zmiennych całkowitych.
Jest to okno.
To się nazywa m, i można Sklep z liczbami całkowitymi w jej wnętrzu.
>> Co jeśli to powiedzieć, int star?
Dobrze, że jest dość podobna.
Tworzę pole nazywa.
Jest w stanie utrzymać int gwiazdy, wskaźniki do liczb całkowitych.
Więc jestem kolorowanie to Zielona-owski, jak również.
>> Wiem, że ma to coś do czynienia z liczbą całkowitą,
ale sama nie jest liczbą całkowitą.
Ale to prawie ten sam pomysł.
Stworzyłem okno.
Obie te prawa teraz mieszkam na stosie.
Dałem im obie nazwy.
>> int gwiazda b równa malloc rozmiar int.
Ten może być trochę trudne.
Poświęć chwilę i pomyśleć o tym, co spodziewałby się zdarzyć na tym schemacie.
int gwiazda b równa malloc rozmiar int.
>> No to nie wystarczy utworzyć jedno pole.
To rzeczywiście tworzy dwa pola.
A to wiąże, również ustanawia punkt w związku.
Mamy przydzielony jeden blok pamięci na stercie.
Zauważ, że w prawym górnym rogu okno nie ma nazwy.
>> Mamy mallocd go.
Istnieje on na stercie.
Ale b ma imię.
Jest to wskaźnik o nazwie zmiennej b.
Że mieszka na stosie.
>> Więc jest to kawałek pamięci który wskazuje na inny.
b zawiera adres z tego bloku pamięci.
To nie ma nazwy inaczej.
Ale wskazuje na to.
Więc, gdy mówimy, int gwiazda b równa Rozmiar malloc int, że tam,
że strzałka, która pojawiła się na tam po prawej stronie, że cała sprawa,
Będę musiał się wydawać znowu, jest to, co się dzieje.
Wszystko to dzieje się w że jednej linii kodu.
Teraz będziemy mieli trochę więcej znowu proste.
A równa ampersand m.
Pamiętasz, co się równa znaku & m jest?
Dobrze, że to dostaje adres M.
Lub umieścić bardziej schematycznie, a punkty do m.
>> A równa się b.
OK, więc o jeszcze jeden.
A równa się b.
Co się stanie na wykresie tym razem?
>> Dobrze pamiętam, że prace operatora przypisania
przez przypisanie wartości na Prawo do wartości po lewej stronie.
Więc zamiast skierowana M, A teraz wskazuje w tym samym miejscu, że B punktów.
A nie wskazują na B, A wskazuje, gdzie b punktów.
>> Jeśli szpiczasty do b, które były równe ampersand b.
Ale zamiast równa b prostu Oznacza to, że i b są teraz
wskazując tym samym adresem, ponieważ wewnątrz b jest tylko adres.
Teraz wewnątrz a jest tego samego adresu.
m wynosi 10, prawdopodobnie Najprostszą rzeczą
zrobiliśmy w trochę.
Umieścić 10 w polu.
Gwiazda b równa m plus 2, pamiętam z Wskaźniki wideo, co nasza gwiazda b oznacza.
Jedziemy do wyłuskiwania b i umieścić jakaś wartość w tym miejscu pamięci.
W tym przypadku 12.
>> Kiedy więc dereference punktu Przypomnijmy, że po prostu podróżować w dół strzałkę.
Albo innymi słowy, mamy przejść do tego adresu pamięci
i manipulować nim w jakiś sposób.
Kładziemy jakąś wartość tam.
W tym przypadku gwiazdy b M plus 2 równa jest po prostu
przejść do zmiennej wskazywanej przez b, przejść do pamięci wskazywanego przez b,
i umieścić m plus 2 tam, 12.
>> Teraz uwolnić b.
Co się dzieje, kiedy zwolnić b?
Pamiętaj, co powiedziałem wolne środki.
Co ja mówię, kiedy zwolnić b?
>> Skończyłem pracę z nim, prawda?
I w zasadzie zrezygnować z pamięci.
Daję go z powrotem do systemu.
Nie potrzebuję już tego jest co mam im powiedzieć, OK?
>> Teraz, jeśli powiem, star wynosi 11 prawdopodobnie można
już powiedzieć, że coś złego będzie się działo tutaj, prawda?
I rzeczywiście, jeśli Próbowałem, że prawdopodobnie poniósłby winy segmentacji.
Bo teraz, choć wcześniej, że fragment pamięci
było coś, co miałem dostęp do nich w tym momencie
teraz mam dostępu do pamięci, że nie jest dla mnie prawnego dostępu.
>> A jak będzie prawdopodobnie pamiętam, kiedy dostęp do pamięci
że nie powinniśmy dotykać, to jest najczęstszą przyczyną
z segmentacji przyczepić. I tak mój program
będzie katastrofy, gdy starałem się to zrobić.
Więc jeszcze raz, że to dobry pomysł, aby uzyskać dobry praktyka i dobre nawyki zakorzenione
podczas pracy z malloc i wolna, tak, że nie cierpią segmentacji
błędy, i że używasz Twój dynamicznie przydzielane
Pamięć odpowiedzialnie.
>> Jestem Doug Lloyd to CS50.