Witam i witam ponownie. W tym wykładzie chcę porozmawiać o dynamicznej alokacji pamięci.
Jest to bezpośrednio związane ze wskaźnikami, możesz to zastosować tylko
na wskaźnikach. Więc zacznijmy.
Dlatego za każdym razem, gdy
definiujesz zmienną w c, kompilator automatycznie przydziela odpowiednią ilość pamięci na podstawie typu danych.
Widzieliśmy to przez cały czas. Kiedy tworzymy liczby całkowite, zmiennoprzecinkowe i podwójne, nie musimy przydzielać żadnej pamięci.
Kompilator zrobi to za Ciebie. W rzeczywistości przydziela trochę pamięci.
Nawiasem mówiąc, to samo dotyczy wskaźników. Kiedy tworzysz wskaźnik, przydzielana
jest pamięć, tak że przechowuje typ wskaźnika, adres.
To nie znaczy, że pamięć jest przydzielona dla tego adresu.
Do tego momentu, ilekroć przypisujemy dane do wskaźnika -
do wskaźnika, zawsze przypisywaliśmy istniejącą zmienną.
Więc jeśli chcieliśmy
przypisać dane do wskaźnika, użyliśmy ampersand adresu operatora
na zmiennej, której zmienna ma już przydzieloną pamięć.
Ale co by było, gdybyś chciał utworzyć wskaźnik i nie chciał przypisać mu
adresu operatora, chciałeś dynamicznie alokować pamięć. O tym jest cały ten wykład.
Dlatego często pożądane jest dynamiczne przydzielanie pamięci podczas
działania programu. Przydziel pamięć tak, jak potrzebujesz.
Jeśli masz program przeznaczony do wczytywania zestawu danych z pliku
do tablicy w pamięci, masz trzy możliwości.
Możesz zdefiniować tablicę tak, aby zawierała maksymalną liczbę możliwych elementów, które kompilują się w czasie,
jest to stały rozmiar.
Jeśli zdefiniujesz tablicę, która ma 50 elementów, będzie
zawierała tylko 50 elementów. Kompilator ustala, że jest to
50, przydzieli tyle pamięci podczas działania.
Możesz użyć tablicy o zmiennej długości do wymiaru rozmiaru środowiska wykonawczego tablicy.
Porozmawialiśmy trochę o tych tablicach o zmiennej długości,
nie są one obsługiwane aż do C11. Właściwie wyjmują C11, dodają C99.
Tutaj możesz wstawiać zmienne.
Ale nadal są to w pewnym sensie stały rozmiar,
ponieważ wszystko to oznacza, że tablice połączone ze zmiennymi oznacza tylko, że możesz przekazywać zmienne dla rozmiarów.
Ale nadal są statyczne.
Lub najlepszym wyborem jest dynamiczna alokacja tablicy w zależności od potrzeb.
Istnieją różne funkcje c, które możesz wywołać, aby to zrobić.
Dlatego bardzo przydatna będzie możliwość dynamicznego przydzielania pamięci.
Tak więc przy pierwszym podejściu, które robiliśmy do tej pory, niezależnie od tego, czy
jest to tablica, czy typ danych, jest to stały rozmiar.
Musisz zdefiniować swoją tablicę tak, aby zawierała maksymalną liczbę elementów,
które będą bezpośrednio w tablicy.
Więc zrobiłbyś coś takiego, int dataArray [1000].
Oznacza to jednak, że plik danych nie może zawierać więcej niż tysiąc elementów.
Jeśli tak, Twój program się zepsuje.
Musisz więc mieć nadzieję, że plik, który czytasz, nie zawiera wielu danych.
Twój program nie będzie działał z dużymi zestawami plików lub dużymi plikami.
A jeśli chcesz pracować z dużymi plikami, musisz cofnąć się i powiększyć tablicę.
Musisz zmienić rozmiar, ale potem
musisz go ponownie skompilować na wszystkich tych rzeczach, jest to czas na kompilację.
Bez względu na to, jaką wartość wybierzesz, zawsze masz szansę
ponownie napotkać ten sam problem w przyszłości, ponieważ jest to stały rozmiar.
Ten rozmiar jest określany podczas kompilowania kodu,
nie dostosowuje się podczas uruchamiania programu.
Nie zmienia się dynamicznie.
Korzystając z funkcji dynamicznej alokacji pamięci, możesz uzyskać pamięć, której potrzebujesz.
Takie podejście umożliwia przydzielanie pamięci podczas wykonywania programu.
Pomyśl więc o zaletach tego. Przede wszystkim nie
tworzysz mnóstwa pamięci, której możesz nie
użyć, a utworzysz tylko tyle, ile potrzebujesz.
A jeśli potrzebujesz więcej, możesz przydzielić więcej.
Nie musisz wracać, ponownie kompilować i zmieniać rozmiaru.
Tak więc dynamiczna alokacja pamięci jest drogą do zrobienia.
Zależy to od koncepcji wskaźnika i
stanowi silną zachętę do używania wskaźników w kodzie.
Więc rozmawialiśmy o zaletach wskaźników i być
może pomyśleliście sobie dobrze, w porządku, to fajna koncepcja, ale dlaczego musimy
ich używać, jest to
jeden z głównych powodów, dla których można dynamicznie przydzielać pamięć.
I znowu, co to jest - C polega na byciu wydajnym językiem
i nie używaniu mnóstwa pamięci.
Więc c działa na systemach wbudowanych, programowaniu w czasie rzeczywistym
i jest to jeden z powodów, ponieważ możesz ograniczyć ilość używanej
pamięci w zależności od potrzeb.
Tak więc dynamiczna alokacja pamięci umożliwia dynamiczne przydzielanie pamięci do przechowywania danych
podczas wykonywania programu.
Dynamiczne przydzielanie pamięci jest możliwe tylko
dzięki dostępności wskaźników.
Ponieważ masz adres i możesz
zmienić wartość wskazywaną przez wskaźnik, możesz ponownie dostosować pamięć.
Większość programów produkcyjnych będzie korzystać z dynamicznej alokacji pamięci.
Jeśli piszesz kod w c, użyjesz tego.
Nawet jeśli jesteś początkującym, będziesz używać
dynamicznej alokacji pamięci. Większość przydatnych programów będzie wykorzystywać tę koncepcję.
Dynamiczne przydzielanie danych umożliwia tworzenie wskaźników w czasie wykonywania, które są
wystarczająco duże, aby pomieścić ilość danych potrzebnych do wykonania zadania,
dzięki czemu nie marnujesz pamięci. Istotny.
Musimy również porozmawiać o stosie i stosie.
Istnieją dwa sposoby przechowywania pamięci w programie, dwie różne
struktury danych, które możesz przechowywać na stosie lub możesz przechowywać dane
na stercie.
Dynamiczna alokacja pamięci rezerwuje wszystko na stercie.
Nie będziemy wchodzić w szczegóły tego, jak są one zorganizowane, ale zasadniczo.
Kiedy przechowujesz dane na stercie, pozwala to na
więcej zmian.
Możesz dowolnie zmieniać rozmiar obiektów danych i utrzymuje się
on znacznie dłużej, gdy alokujesz pamięć w
stercie, trzyma się całego programu.
Kiedy używasz stosu, jest to bardziej ograniczone.
Stos jest używany do wszystkiego, od argumentów funkcji i zmiennych lokalnych.
Tam wszystko jest przechowywane.
Dlatego rozmawialiśmy o stosie wywołań.
Przyjrzano się metodom
i funkcjom. Używam metod od czasu do czasu, ale metody są tak naprawdę terminem
zorientowanym obiektowo, więc funkcje.
Wszystko związane z funkcjami jest tworzone na stosie.
Oznacza to, że kiedy wykonujesz funkcję,
zostaje ona umieszczona na stosie. Zmienne lokalne są umieszczane na stosie.
Po wyjściu z funkcji wszystko zostanie usunięte.
Dzięki temu pamięć znajdująca się na stosie nie trzyma się zbyt długo.
To jeden z powodów, dla których dynamicznie przydzielasz pamięć,
która znajduje się
na stercie, ponieważ kontrolujesz, kiedy jej używasz, a kiedy jej nie używasz, przydzielasz ją i usuwasz.
Rzeczy na stosie, których nie kontrolujesz. Jest automatycznie
usuwany, automatycznie przydzielany.
Zatem zmienne lokalne, zmienne wewnątrz funkcji, takich jak main, są
tworzone na stosie i tak dalej.
Pamięć na stercie jest inna, jest kontrolowana przez Ciebie, programistę.
Kiedy alokujesz pamięć na stercie, do Ciebie należy śledzenie, kiedy przydzielona pamięć
nie jest już potrzebna, więc musisz ją usunąć.
Musisz zwolnić miejsce,
gdy nie jest już używane. Jest to ważne,
ponieważ pamięć jest bardzo, bardzo rzadkim zasobem.
Dziś mamy dużo pamięci, że możesz uruchomić komputer, 12 koncertów, 16
koncertów cokolwiek to jest. Ale w przypadku
programów, które są osadzone i działają na urządzeniach,
niekoniecznie masz tyle pamięci. Dlatego chcesz kontrolować zużycie pamięci, a
także chcesz zwolnić pamięć, gdy skończysz jej używać, aby inne aplikacje
mogły z niej korzystać.
Ponownie, ważniejsze w niskopoziomowych systemach typu osadzonego.
Ale jest to wolność, której nie ma wiele języków. Ta możliwość kontrolowania
pamięci menedżera przez programistę może sprawić, że program
będzie znacznie wydajniejszy i znacznie szybszy.
Więc w następnym wykładzie porozmawiamy o tym, jak możesz
to zrobić, jakie funkcje możesz wywołać. Oczywiście istnieją różne funkcje, które można wywołać,
aby przydzielić pamięć do wolnej pamięci. Dziękuję Ci.