Dynamiczna alokacja pamięci w C++

Dynamiczna Alokacja Pamieci W C



Zwykle, używając kodów źródłowych w języku programowania C++, kompilator ręcznie przydziela pamięć zmiennej do przechowywania danych. Mówi się, że jest to przydział pamięci statycznej. Jest to stała pamięć, której nie można zmienić po zadeklarowaniu. W przypadku tego typu przydziału pamięci system operacyjny używa stosu do przechowywania danych. W alokacji statycznej pamięć jest przydzielana przed rozpoczęciem wykonywania kodu źródłowego.

Podczas gdy w dynamicznej alokacji pamięci pamięć jest przydzielana w momencie rozpoczęcia wykonywania. Ta pamięć jest przydzielana ręcznie przez programistę w czasie wykonywania, co jest również znane jako alokacja pamięci w czasie wykonywania w języku C++. Rozmiar pamięci dynamicznej można zmienić w dowolnej pozycji w programie, ponieważ w momencie deklaracji nie podajemy rozmiaru, który można naprawić. Podajemy tylko wartość bezpośrednio do zmiennej.

Różnica przydziału pamięci dla normalnych zmiennych

W normalnych zmiennych pamięć przydzielana przez kompilator jest przydzielana i zwalniana automatycznie. Gdy pamięć jest przydzielana dynamicznie przez programistę, musi on następnie usunąć lub zwolnić pamięć, gdy jest ona bezużyteczna w dalszym wykonywaniu kodu źródłowego. Ta sytuacja powoduje „wyciek pamięci”, gdy program zostaje zakończony, gdy pamięć nie jest zwolniona.







Operatory alokacji dynamicznej

W C++ dwa operatory pomagają w alokacji i zwalnianiu pamięci: „new” i „delete”, które są używane do alokacji i zwalniania pamięci w lepszy sposób.



Nowy operator

Oznacza żądanie przydziału pamięci. Operator new inicjuje pamięć i zwraca adres tej przydzielonej pamięci do zmiennej wskaźnikowej, jeśli dostępna jest wystarczająca ilość pamięci.



Obiekt wskaźnika = Nowy dane - rodzaj ;

Usuń operatora

Podobnie jak operator new, operator delete służy do usuwania przydzielonej pamięci. W C++ programista może używać tego operatora do zwalniania alokacji.





# Usuń zmienną wskaźnika;

Przykład 1

W tym przykładzie wprowadzimy dwa wskaźniki: jeden jest wskaźnikiem typu integer, a drugi jest wskaźnikiem zmiennoprzecinkowym. Wskaźniki są inicjowane za pomocą znaku gwiazdki.

# Int * pointInt;
# Float *pointfloat;

Korzystając z tych dwóch drukarek, będziemy dynamicznie przydzielać pamięć.



Rola wskaźników w alokacji dynamicznej:
Pamięć przestrzeni magazynowej rozwijana jest w postaci bloków. Ilekroć wykonujemy program lub wykonujemy jakąkolwiek operację, pamięć jest przydzielana do tego konkretnego celu. Ta pamięć ma specjalny adres, który jest powiązany z programem, który identyfikuje, który proces lub program ma dostęp do tej pamięci. Dostęp do dowolnego gniazda pamięci odbywa się poprzez adres, do którego należy. Więc ten adres jest przechowywany przez wskaźniki. Krótko mówiąc, potrzebujemy wskaźników, aby uzyskać dostęp do pamięci i tym samym przydzielić określoną część pamięci do dowolnego zadania. Do przechowywania adresów potrzebne są wskaźniki.

Ponieważ słowo kluczowe „new” jest używane do dynamicznej alokacji pamięci w alokacji ręcznej, pamięć jest przydzielana przez kompilator. Nie musimy przydzielać pamięci w czasie wykonywania. Ale ponieważ alokacja dynamiczna jest losowa, musimy zidentyfikować wskaźniki, a dla procesu wiązania używany jest ten nowy operator.

# Pointint = nowy int;

Podobnie, zmiennoprzecinkowy wskaźnik jest związany w podobny sposób. Po procesie wiązania przypiszemy do pamięci dowolną wartość, którą chcemy zarezerwować na dowolną operację. Deklarując wskaźnik, przypisujemy do pamięci określoną wartość.

# *pointInt = 50;

Deklarowana jest również wartość zmiennoprzecinkowa dla punktów zmiennoprzecinkowych. Wyświetl wartości po przypisaniu.

Jak omówiliśmy, operator „nowy” służy do przydzielania, podczas gdy „usuwanie” służy do zwalniania pamięci. Kiedy więc wykonasz zadanie lub operację w kodzie, usuniemy pamięć, którą przydzieliliśmy temu zadaniu.

Lepiej zwolnić tę część pamięci, aby każdy inny proces mógł z tego skorzystać. Zastosujemy tę alokację do obu wskaźników.

Usuń punkt platforma ;

Po zapisaniu kodu w edytorze tekstu terminal Ubuntu umożliwia wykonanie kodu źródłowego w pliku za pomocą kompilatora g++.

$ g++ -o mem mem.c
$ ./mem

Po wykonaniu zobaczysz wartości przypisane do pamięci.

Przykład 2

Ten przykład obejmuje interakcję użytkownika. Weźmiemy zmienną liczbową, która będzie zawierała wartość od użytkownika. Ten program zapisze wynik w GPA uczniów. Wszystkie wyniki zostaną zapisane w czasie wykonywania.

Gdy użytkownik wprowadza liczbę uczniów, pamięć jest przydzielana dla każdego numeru. W tym miejscu inicjowany jest wskaźnik typu float, który będzie używany w alokacji pamięci wyników.

Bierzemy wskaźnik w liczbie zmiennoprzecinkowej, ponieważ GPA jest w notacji dziesiętnej. Bierzemy tablicę typu wskaźnika dla GPA, ponieważ może to skutkować liczbą uczniów.

Ptr = Nowy platforma [ na jednego ]

Ta tablica wskaźników ze słowem kluczowym „new” powiąże wykonanie z pamięcią. GPA zostanie wprowadzony dla każdego ucznia. Ponieważ nie znamy liczby uczniów, których użytkownik chce dodać, użyliśmy pętli for, aby wprowadzić GPA do wprowadzonej liczby. W każdym powtórzeniu pętli użytkownik proszony jest o wpisanie wyniku identyfikującego ucznia. Po zapisaniu wyniku ponownie użyjemy pętli, aby wyświetlić wszystkie GPA uczniów. Ostatecznie tablica typu wskaźnika jest usuwana, ponieważ cel dynamicznego przechowywania został osiągnięty.

Usuwać [ ] ptr ;

Teraz wykonamy powyższy kod. Użytkownik zostanie najpierw poproszony o podanie liczby studentów. Następnie zostanie wprowadzony GPA dla każdego ucznia.

Przykład 3

W tym przykładzie użyto operatorów new i delete dla obiektu klasy. Ta klasa zawiera prywatną zmienną typu integer, która przechowuje wiek. W części publicznej klasy tworzony jest konstruktor, który zainicjuje wiek na liczbę „10”. Zastosowano tutaj inną funkcję, która wyświetli wiek zainicjowany w konstruktorze.

Teraz przejdziemy do głównego programu alokacji dynamicznej. Obiekt klasy jest tworzony dynamicznie.

Student * ptr = Nowy student ( ) ;

Gdy obiekt zostanie utworzony, konstruktor zostanie zaimplementowany automatycznie. Zostanie wykonane wywołanie funkcji w celu uzyskania wieku. Odbędzie się to za pośrednictwem ptr.

Ptr - > getAge ( ) ;

A na końcu pamięć zostanie zwolniona.

Wniosek

Dynamiczna alokacja pamięci jest przydzielana w czasie wykonywania przez programistę zamiast stałej pamięci identyfikowanej przez kompilator. Alokacja ta jest losowa i może zostać wyeliminowana po jej wykorzystaniu. Podczas gdy w większości przypadków przed usunięciem proces wykonywania zatrzymuje się, a ta dynamiczna alokacja powoduje następnie wycieki pamięci. Zjawisko to zaimplementowaliśmy na różne sposoby w systemie Ubuntu Linux przy użyciu języka programowania C++.