Dzwon.

Są ci, którzy przeczytali tę wiadomość przed tobą.
Subskrybuj odbieranie artykułów świeżych.
E-mail
Nazwa
Nazwisko
Jak chcesz przeczytać dzwonek
Bez spamu

Dynamiczna alokacja pamięci jest niezbędna do skutecznego korzystania z pamięci komputera. Na przykład napisaliśmy jakiś rodzaj programu, który przetwarza tablicę. Podczas pisania tego programu konieczne było zadeklarowanie tablicy, czyli, aby ustawić go o stałym rozmiarze (na przykład od 0 do 100 elementów). Następnie ten program nie będzie uniwersalny, ponieważ może przetworzyć tablicę nie więcej niż 100 elementów. A jeśli potrzebujemy tylko 20 elementów, ale w pamięci znajduje się miejsce poniżej 100 elementów, ponieważ deklaracja tablicy była statyczna, a takie użycie pamięci jest niezwykle nie skuteczne.

W C ++ nowe i usuwane operacje są zaprojektowane tak, aby dynamicznie dystrybuować pamięć komputera. Nowa operacja przydziela pamięć z obszaru Darmowej pamięci, a operację Usuń obsługuje alokowaną pamięć. Przydzielona pamięć, po jego użyciu powinna zostać zwolniona, więc operacje nowe i usuwane są używane w parach. Nawet jeśli nie zwolnij pamięci jawnie, będzie wolne od zasobów OS po zakończeniu programu. Zalecam nie zapomnieć o operacji usuwania.

// Przykład wykorzystania działania nowego INT * PTRVALUE \u003d Nowy Int; // gdzie ptrvalue jest wskaźnikiem do dedykowanej sekcji pamięci typu Int // Nowy - działanie podświetlania wolnej pamięci dla utworzonego obiektu.

Nowa operacja tworzy określony obiekt typu, przydziela pamięć do niego i zwraca poprawny wskaźnik typu do tej witryny pamięci. Jeśli pamięć nie można wybrać, na przykład, w przypadku braku wolnych obszarów, wskaźnik zerowy jest zwracany, czyli wskaźnik zwróci wartość 0. Alokacja pamięci jest możliwa dla dowolnego typu danych: int., pływak.,podwójnie., Zwęglać. itp.

// Przykład korzystania z Usuń: Usuń działanie PTRValue; // gdzie ptrvalue jest wskaźnikiem do dedykowanej sekcji pamięci typu Int // Usuń - operacja zwalniania pamięci

Opracujemy program, w którym zostanie utworzona zmienna dynamiczna.

// NEW_DELETE.CPP: Określa punkt wejściowy dla aplikacji konsoli. #Include "stdafx.h" #include << "ptrvalue = " \u003c\u003c * ptrvalue \u003c\u003c ENDL; Usuń ptrvalue; // zwolnienie pamięci systemu ("pause"); return 0; }

// Kod kodu :: Bloki

// kod Dev-C ++

// NEW_DELETE.CPP: Określa punkt wejściowy dla aplikacji konsoli. #Zawierać. Za pomocą przestrzeni nazw STD; Int Main (int Argc, Char * Argv) (int * ptrvalue \u003d Nowy INT; // Dynamiczna alokacja pamięci pod względem obiektu INT * PTRValue \u003d 9; // inicjalizacja obiektu przez wskaźnik // int * ptrvalue \u003d nowy int (9); inicjalizacja może być wykonywana natychmiast po zadeklarowaniu dynamicznego obiektu<< "ptrvalue = " \u003c\u003c * ptrvalue \u003c\u003c ENDL; Usuń ptrvalue; // Uwolnienie pamięci zwrotnej 0; ) \u003c/ p\u003e \u003cp\u003e (! lang: w strunowy 10 wyświetlana jest metoda ogłoszenia i inicjalizacji dziewięciu obiektów dynamicznych, wszystko jest potrzebne do określenia wartości w okrągłych wspornikach po typie danych. Wynik programu jest pokazany na rysunku 1.

PTRVALUE \u003d 9 Aby kontynuować, naciśnij dowolny klawisz. . .

Rysunek 1 - Zmienna dynamiczna

Tworzenie dynamicznych tablic

Jak wspomniano wcześniej, tablice mogą być również dynamiczne. Najczęściej nowe i usuwane operacje służą do tworzenia dynamicznych tablic, a nie tworzyć zmiennych dynamicznych. Rozważ fragment kodu do tworzenia jednowymiarowej dynamicznej tablicy.

// ogłoszenie jednowymiarowej tablicy dynamicznej dla 10 elementów: float * ptarray \u003d nowa pływak; // gdzie ptarray jest wskaźnikiem do dedykowanego obszaru pamięci dla tablicy rzeczywistej liczby pływaków typu // w nawiasach kwadratowych wskazują rozmiar tablicy

Po tym, jak dynamiczna tablica stała się niepotrzebna, konieczne jest zwolnienie obszaru pamięci, która wyróżnia się pod nim.

// Usuwanie pamięci przypisania w ramach jednowymiarowej tablicy dynamicznej: Usuń PTARRAY;

Po operatorze Usuń, wsporniki kwadratowe są umieszczone, co sugerują, że witryna pamięci jest zwolniona, przydzielona do określonej tablicy. Opracujemy program, w którym tworzymy jednowymiarową dynamiczną tablicę wypełnioną liczbami losowymi.

// NEW_DELETE_ARRAY.CPP: Określa punkt wejściowy dla aplikacji konsoli. #Zawierać."stdafx.h" #include !} // w pliku nagłówka // w pliku nagłówka < 10; count++) ptrarray = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10 cout << "array = "; for (int count = 0; count < 10; count++) cout << setprecision(2) << ptrarray << " "; delete ptrarray; // высвобождение памяти cout << endl; system("pause"); return 0; }

// Kod kodu :: Bloki

// kod Dev-C ++

// NEW_DELETE_ARRAY.CPP: Określa punkt wejściowy dla aplikacji konsoli. #Zawierać. // w pliku nagłówka Zawiera czas funkcji prototypu () #include // w pliku nagłówka Zawiera funkcję prototypową () #include #Zawierać. Za pomocą przestrzeni nazw STD; Int main (int argc, char * argv) (srand (czas (0)); // generacja liczb losowych pływaków * ptrarray \u003d nowy float; // tworząc dynamiczny zestaw liczb rzeczywistych dla dziesięciu elementów (int Liczyć \u003d 0 ; Liczba< 10; count++) ptrarray = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10 cout << "array = "; for (int count = 0; count < 10; count++) cout << setprecision(2) << ptrarray << " "; delete ptrarray; // высвобождение памяти cout << endl; system("pause"); return 0; }

Utworzona jednowymiarowa dynamiczna tablica jest wypełniona losowymi liczbami rzeczywistymi uzyskanymi przez funkcje generowania liczb losowych, a liczby są generowane w zakresie od 1 do 10, interwał jest ustawiony tak - Rand ()% 10 + 1 . Aby uzyskać losowe liczby rzeczywiste, operacja podziału jest wykonywana przy użyciu wyraźnego rozwiązania do rzeczywistego rodzaju mianownika - pływaka ((Rand ()% 10 + 1)). Aby pokazać tylko dwa znaki dziesiętne za pomocą funkcji SetPrecysion (2) , prototyp tej funkcji znajduje się w pliku nagłówka. . Funkcja Time (0) wysyła generator liczby losowej o tymczasowej wartości, a zatem okazuje się odtworzyć losowość wystąpienia liczb (patrz rysunek 2).

Array \u003d 0,8 0,25 0,86 0.5 2,2 10 1,2 0,3 0.89 3.5 Aby kontynuować, naciśnij dowolny klawisz. . .

Rysunek 2 - Dynamiczna tablica w C ++

Po zakończeniu pracy z tablicą zostanie usunięty, a zatem pamięć jest uwalniana pod jego pamięcią masową.

Jak tworzyć i pracować z jednowymiarowymi dynamicznymi tablicami, których się nauczyliśmy. Teraz rozważ fragment kodu, który pokazuje, jak zadeklarowany jest dwuwymiarowa dynamiczna tablica.

// ogłoszenie dwuwymiarowej dynamicznej tablicy dla 10 elementów: float ** ptarray \u003d Nowy float *; // Dwie linie w formularzach dla (int Liczyć \u003d 0; Liczba< 2; count++) ptrarray = new float ; // и пять столбцов // где ptrarray – массив указателей на выделенный участок памяти под массив вещественных чисел типа float

Po pierwsze, drugi rzędu wskaźnik float ** PTARRAY jest ogłoszony, co odnosi się do tablicy wskaźników pływakowych *, gdzie rozmiar tablicy jest dwa . Po tym, w cyklu C dla każdego wiersza tablicy zadeklarowanej Rząd 2.jest pamięć dla pięciu elementów. W rezultacie otrzymuje się dwuwymiarową dynamiczną tablicę ptarray. Kurwij przykład pamięci pamięci dla dwuwymiarowej dynamicznej tablicy.

// Usuwanie pamięci przypisania w ramach dwuwymiarowej dynamicznej tablicy: dla (int Liczyć \u003d 0; liczba< 2; count++) delete ptrarray; // где 2 – количество строк в массиве

Ogłoszenie i usunięcie dwuwymiarowej tablicy dynamicznej przeprowadza się przy użyciu cyklu, jak pokazano powyżej, konieczne jest zrozumienie i zapamiętanie, jak się skończy. Opracowujemy program, w którym tworzymy dwuwymiarową dynamiczną tablicę.

// new_delete_array2.cpp: Określa punkt wejściowy dla aplikacji konsoli. #Include "stdafx.h" #include #Zawierać. #Zawierać. < 2; count++) ptrarray = new float ; // и пять столбцов // заполнение массива for (int count_row = 0; count_row < 2; count_row++) for (int count_column = 0; count_column < 5; count_column++) ptrarray = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10 // вывод массива for (int count_row = 0; count_row < 2; count_row++) { for (int count_column = 0; count_column < 5; count_column++) cout << setw(4) <

// Kod kodu :: Bloki

// kod Dev-C ++

// new_delete_array2.cpp: Określa punkt wejściowy dla aplikacji konsoli. #Zawierać. #Zawierać. #Zawierać. #Zawierać. Za pomocą przestrzeni nazw STD; Int Main (int Argc, Char * Argv) (Srand (Time (0)); // Generowanie liczb losowych // Dynamiczne tworzenie dwuwymiarowej tablicy liczb realnych dla dziesięciu elementów Float ** Ptrarray \u003d Nowy Float *; // dwa wiersze w tablicy dla (int liczenia \u003d 0; liczba< 2; count++) ptrarray = new float ; // и пять столбцов // заполнение массива for (int count_row = 0; count_row < 2; count_row++) for (int count_column = 0; count_column < 5; count_column++) ptrarray = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10 // вывод массива for (int count_row = 0; count_row < 2; count_row++) { for (int count_column = 0; count_column < 5; count_column++) cout << setw(4) <

Po uzyskaniu tablicy funkcja SETW () została użyta, jeśli nie zapomnisz, to wymaga miejsca określonego rozmiaru pod danymi wyjściowymi. W naszym przypadku, dla każdego elementu tablicy czterech pozycji, umożliwia wyrównanie, w kolumnach, liczbach różnych długości (patrz rysunek 3).

2.7 10 0,33 3 1,4 6 0,67 0,86 1,2 0,44 Aby kontynuować, naciśnij dowolny klawisz. . .

Rysunek 3 - Dynamiczna tablica w C ++

Więc. Trzeci typ, najciekawszy w tym temacie dla nas - dynamiczny typ pamięci.

Jak wcześniej pracowaliśmy z tablicami? Int, jak teraz pracujemy? Wyróżniamy tyle, ile potrzebujesz:

#Zawierać. < stdio.h> #Zawierać. < stdlib.h> Int Main () (rozmiar_t size_t; // Utwórz wskaźnik int // - W istocie pusta tablica. Int * Lista; Skanf ( "% Lu"i rozmiar); // Wybierz pamięć do rozmiarów rozmiarów Int rozmiar // i nasza "pusta tablica" odnosi się teraz do tej pamięci. Lista \u003d (int *) malloc (rozmiar * sizeof (int)); dla (int i \u003d 0; ja< size; ++i) { scanf ("% d" < size; ++i) { printf ("% d", * (Lista + i)); ) // nie zapomnij zająć się! Wolny (lista); ) // *

Void * malloc (rozmiar_t size_t);

Jednak w ogóle, ta funkcja wybiera bajt rozmiaru niezainicjowanej pamięci (nie zeros i gruz).

Jeśli wybór przekazał pomyślnie, wskaźnik zostanie zwrócony do pierwszego bajtu przydzielonej pamięci.

Jeśli nieudany - null. Errno będzie również równy enomemowi (przyjrzymy się na tę wspaniałą zmienną później). To znaczy, było bardziej poprawne do napisania:

#Zawierać. < stdio.h> #Zawierać. < stdlib.h> Int Main () (rozmiar_tiza_t; Int * Lista; Scanf ( "% Lu"i rozmiar); Lista \u003d (int *) malloc (rozmiar * sizeof (int)); Jeśli (lista \u003d\u003d null) (błąd goto;) dla (int i \u003d 0; ja< size; ++i) { scanf ("% d", Lista + i); ) dla (int I \u003d 0; ja< size; ++i) { printf ("% d", * (Lista + i)); ) Wolne (lista); Powrót 0; Błąd: Powrót 1; ) // *

Czysty wskaźnik zerowy nie potrzebuje

#Zawierać. < stdlib.h> Int Main () (za darmo (Null);)

- W tym samym skrzyżowaniu wszystko przejdzie normalnie (nie zrobi nic), ale w bardziej egzotycznych przypadkach może być ostry program.

Obok Malloc i wolny od człowieka może zobaczyć więcej:

    void * Calloc (liczba rozmiarów_t, rozmiar_g);

    Równie, jak i Malloc podświetli pamięć pod liczbą obiektów według rozmiaru według wielkości bajtu wielkości. Przydzielona pamięć jest zainicjowana przez zera.

    void * RealLOC (Void * PTR, rozmiar size_t);

    Odtwarza (jeśli cokolwiek) pamięć, do której wskazuje PTR, w rozmiarze rozmiaru. Jeśli nie ma wystarczającej ilości miejsca, aby zwiększyć przydzieloną pamięć, do której wskazuje PTR, RealLoc tworzy nowy wybór (alokacja), kopiuje stare dane, do których wskazuje PTR, uwalnia stary wybór i zwraca wskaźnik do wybranej pamięci.

    Jeśli PTR ma wartość NULL, RealLOC jest identyczny z połączeniem Malloc.

    Jeśli rozmiar jest zerowy, a PTR nie jest , wyróżnia się kawałek minimalnej pamięci, a oryginał zostanie zwolniony.

    void * RealLocf (Void * PTR, rozmiar rozmiar_t);

    Walcz z API FreeBSD. Jak RealLoc, ale jeśli nie można go zwolnić, oczyści przyjęty wskaźnik.

    void * VALLOC (rozmiar_g rozmiaru);

    Podobnie jak Malloc, ale przydzielona pamięć jest wyrównana wzdłuż granicy strony.

Dynamiczna alokacja pamięci

Główne problemy aplikacji

Zerowy wskaźnik

Wskaźnik zerowy jest wskaźnikiem, który przechowuje specjalną wartość używaną w celu pokazania, że \u200b\u200bta zmienna wskaźnik nie odnosi się (nie wskazuje) dowolnym obiekcie. W różnych językach programowania jest reprezentowany przez różne stałe.

· Języki C # i Java: Null

· W SI i C ++: 0 lub Null makro. Ponadto, w standardowej C ++ 11, zaproponowano nowy słowo kluczowe NULrptr w celu wyznaczenia wskaźnika zerowego

· W językach Pascal i Ruby: Nil

· W komponencie języka Pascal: Nil

· W Pythonie: Brak

Wskaźniki są trudne do zarządzania. Łatwo jest napisać do indeksu w indeksie, który może spowodować niewielki błąd powtarzalny. Na przykład przypadkowo zmieniłeś adres wskaźnika w pamięci lub nieprawidłowo przydzielono pamięć w celu uzyskania informacji, a następnie oczekuje się zaskoczenia: inna bardzo ważna zmienna używana tylko wewnątrz programu zostanie nadpisana. W tym przypadku trudno będzie odtworzyć błąd. Nie będzie łatwo i zrozumieć, gdzie znajduje się błąd. I nie zawsze jest trywialny do wyeliminowania go (czasami będą musiały przepisać znaczną część programu).

Aby rozwiązać część problemów, istnieją metody ochrony i ubezpieczenia:

Studiował wskaźniki w SI, odkryliśmy możliwość dynamicznej alokacji pamięci. Co to znaczy? Oznacza to, że gdy dynamicznie przydzielona pamięć pamięć nie jest zarezerwowana na etapie kompilacji A w fazie wykonania programu. I daje nam możliwość bardziej efektywnego przydzielenia pamięci, zasadniczo dotyczy tablic. Dzięki dynamicznej alokacji pamięci nie musimy określić rozmiaru tablicy z góry, zwłaszcza że nie zawsze wiadomo, jaki rozmiar powinien być wśród tablicy. Następnie uważamy, jak można przydzielić pamięć.

Funkcja Malloc () jest zdefiniowana w pliku Nagłówek STDLIB.H, służy do zainicjowania wskaźników za pomocą niezbędnej ilości pamięci. Pamięć jest przydzielana z sektora RAM dostępna do dowolnych programów wykonanych na tej maszynie. Argument funkcji Malloc () jest liczbą bajtów pamięci, które chcesz podświetlić, zwraca funkcję - wskaźnik do wybranego bloku w pamięci. Działa funkcja Malloc (), a także jakąkolwiek inną funkcję, nic nowego.

Ponieważ różne typy danych mają różne wymagania pamięci, jakoś musimy nauczyć się uzyskać rozmiar w bajtach dla różnych danych typowych. Na przykład potrzebujemy witryny pamięci w tablicy wartości całkowitej - jest to jeden rozmiar pamięci, a jeśli musimy podświetlić pamięć dla tablicy tego samego rozmiaru, ale już typem jest inny rozmiar. Dlatego konieczne jest w jakiś sposób obliczyć rozmiar pamięci. Można to zrobić za pomocą operacji SizeOf (), która zabiera wyrażenie i zwraca jego rozmiar. Na przykład, sizeof (int) zwróci liczbę bajtów wymaganych do przechowywania wartości typu INT. Rozważ przykład:


Yandex.direct.


#Zawierać. int * ptrvar \u003d malloc (sizeof (int));

W tym przykładzie, w wiersz 3. Wskaźnik PTRVAR jest przypisany adres do witryny pamięci, której rozmiar odpowiada typowi danych int. Automatycznie ta strona pamięci staje się niedostępna dla innych programów. Oznacza to, że po przydzielonej pamięci stanie się niepotrzebne, należy wyraźnie wydać. Jeśli pamięć nie jest wyraźnie zwolniona, na końcu programu pamięć nie jest bezpłatna do systemu operacyjnego, nazywa się to wyciekiem pamięci. Można również określić rozmiar przydzielonego pamięci, który chcesz wybrać Pusty wskaźnik, tutaj jest przykład:



Jak widać, istnieje jedna bardzo silna strona w takim rekordzie, nie powinniśmy nazywać funkcji Malloc () korzystanie z funkcji (pływak). Zamiast tego zostaliśmy przeniesione do wskaźnika Malloc () do typu float, w którym to przypadku rozmiar pamięci automatycznie zmniejsza się automatycznie!

Jest to szczególnie przydatne, jeśli wymagana jest do daleka od wskaźnika, aby zdefiniować:


Float * ptrvar; / *. . . Sto linii kodu * /. . . Ptrvar \u003d malloc (sizeof (* ptrvar));

Jeśli użyłeś projektu alokacji pamięci z operacją SizeOf, musisz znaleźć definicję kodu w kodzie, obejrzyj jego typ danych i tylko wtedy będziesz mógł prawidłowo wybrać pamięć.

Program może przechowywać informacje w pamięci głównej komputera na dwa główne sposoby. Pierwszy z nich wykorzystuje zmienne globalne i lokalne, w tym tablice, struktury i zajęcia. W przypadku globalnych i statycznych zmiennych lokalnych, lokalizacja przechowywania jest ustalana dla całego czasu wykonania programu. W przypadku zmiennych lokalnych pamięć jest podświetlona w stosie. Chociaż w Borland C ++, praca z tymi zmiennymi jest realizowana bardzo wydajnie, ich użycie wymaga programistę wiedzieć z wyprzedzeniem rozmiaru pamięci, która będzie wymagana podczas wykonywania programu.

Drugą metodą przechowywania informacji jest korzystanie z systemu pamięci dynamicznej pamięci Borland C ++. W tej metodzie pamięć do przechowywania informacji jest przydzielana z wolnego obszaru pamięci w razie potrzeby i zwraca, tj. Jest zwolniony, gdy zniknęła potrzebę. Darmowa pamięć znajduje się między obszarem pamięci, w której znajduje się program i stos. Obszar ten nazywa się wiązką (sterty) i jest używany do żądań dynamicznej alokacji pamięci.

Zaletą użycia pamięci dynamicznej jest to, że ta sama pamięć może być używana do przechowywania różnych informacji w procesie wykonania programu. Ponieważ pamięć jest przydzielana w określonym celu i jest zwolniony, gdy jego użycie zostało zakończone, możesz użyć tej samej pamięci w innym punkcie czasu w innych celach w innej części programu. Kolejną zaletą dynamicznej alokacji pamięci jest możliwość tworzenia powiązanych list, drzew binarnych i innych dynamicznych struktur danych.

Rdzeń Dynamicznej alokacji pamięci pamięci języka z jest funkcjami FUNOC () i Free (), które są częściami standardowej biblioteki. Za każdym razem, gdy funkcja Malloc () jest odbierana pamięć do przydzielania pamięci, rozróżnia się część dostępnej pamięci bezpłatnej. Za każdym razem, gdy ta pamięć jest zwolniona za pomocą funkcji Free (), pamięć ta powraca do systemu.

Language C ++ Definiuje dwóch operatorów alokacji dynamicznych pamięci - nowy i usuń.

Standard ANSI C definiuje tylko cztery funkcje alokacji pamięci dynamicznej: Calloc (), Malloc (), Darmowy () i RealLoc (). Jednak Borland C ++ zawiera kilka innych funkcji alokacji dynamicznych pamięci. Podczas kompilowania kodu dla nowoczesnego modelu pamięci 32-bitowej pamięci jest płaskie i zwykle używana tylko cztery standardowe funkcje alokacji pamięci.

Standard ANSI C określa, że \u200b\u200binformacje nagłówka wymagane do dynamicznej alokacji pamięci znajdują się w pliku STDLIB.H. Jednak Borland C ++ pozwala używać plików stdlib.h lub alloc.h. Tutaj używamy pliku nagłówka Stdlib.h, ponieważ zapewnia przenośność. Niektóre inne funkcje alokacji dynamicznej pamięci wymagają plików nagłówka Alloc.h, Malloc.h lub Dos.h. Konieczne jest zwrócenie szczególnej uwagi, na której potrzebny jest plik nagłówka, aby użyć każdej funkcji.

Dynamiczna i statyczna alokacja pamięci. Zalety i wady. Wybór pamięci dla pojedynczych zmiennych przez nowych i usuń operatorów. Możliwe krytyczne sytuacje podczas przydzielania pamięci. Inicjalizacja podczas wysyłania pamięci

1. Dynamiczna i stała) alokacja pamięci. Główne różnice

Aby pracować z tablicami informacyjnymi, programy muszą przydzielić pamięć dla tych tablic. Aby przydzielić pamięć do tablic zmiennych, odpowiednich operatorów, funkcji, a tym podobne są używane w języku programowania C ++ przydziel następujące metody wysyłania pamięci:

1. Statyczny (naprawiony) Przydział pamięci. W tym przypadku pamięć jest przeznaczona tylko raz podczas kompilacji. Rozmiar przydzielonej pamięci jest ustalona i niezmieniona do końca programu. Przykładem takiego wyboru może być tablica 10 liczb całkowitych:

int m; // Masywna pamięć jest przydzielana raz, rozmiar pamięci jest ustalony

2. Dynamiczny wybierz pamięć. W takim przypadku używany jest połączenie nowych operatorów i usuwania operatorów. Nowy operator podkreśla pamięć dla zmiennej (tablicy) w specjalnym obszarze pamięci, która nazywa się "sterty" (sterty). Operator usuwania uwalnia wybraną pamięć. Każdy nowy operator musi dopasować jego oświadczenie Usuń.

2. Zalety i wady stosowania metod alokacji dynamicznych i statycznych

Dynamiczna alokacja pamięci w porównaniu do alokacji pamięci statycznej daje następujące korzyści:

  • pamięć wyróżnia się w razie potrzeby programowo;
  • nie ma dodatkowego kosztu nieużywanej pamięci. Jest on alokowany tak dużo pamięci tak samo niezbędnej i w razie potrzeby;
  • możesz podświetlić pamięć do tablic informacyjnych, którego rozmiar jest oczywiście nieznany. Określanie rozmiaru tablicy powstaje podczas wykonania programu;
  • jest wygodna do redystrybucji pamięci. Lub innymi słowy, wygodne jest przeznaczenie nowego fragmentu dla tej samej tablicy, jeśli musisz podświetlić dodatkową pamięć lub zwolnić niepotrzebne;
  • z statyczną metodą przydziału pamięci trudno jest rozdzielić pamięć dla zmiennej tablicy, ponieważ została już naprawona. W przypadku dynamicznej metody wyboru odbywa się to po prostu i wygodnie.

Zalety metody alokacji pamięci statycznej:

  • statyczna (stała) alokacja pamięci jest lepsza do użycia, gdy rozmiar tablicy informacyjnej jest oczywiście znana i jest niezmieniona przez cały cały program;
  • allocation pamięci statycznej nie wymaga dodatkowych operacji zwalniania za pomocą operatora Usuń. Stąd wynika z redukcji błędów programowania. Każdy nowy operator musi pasować do operatora usuwania;
  • widok na naturalność (naturalność) na kod programu, który działa z tablicami statycznymi.

W zależności od zadania programista musi być w stanie poprawnie określić, który metoda przydzielania pamięci jest odpowiednia dla określonej zmiennej (tablica).

3. Jak przydzielić operator pamięci nowych dla jednej zmiennej? Całkowity kształt.

Ogólna forma przydzielania pamięci dla pojedynczego operatora zmiennego Nowa ma następujący formularz:

pTRNAME. \u003d Nowy typ;
  • pTRNAME. - nazwa zmiennej (wskaźnika), która wskaże wybraną pamięć;
  • rodzaj - zmienna typu. Rozmiar pamięci jest przydzielany jako wystarczający do pomieszczenia w nim wartości zmiennej tego typu rodzaj .
4. Jak zwolnić pamięć przydzieloną dla pojedynczej zmiennej operatora Usuń? Ogólny formularz

Jeśli pamięć dla zmiennej jest podświetlona przez nowego operatora, a następnie po zakończeniu użycia zmiennej, pamięć ta musi zostać zwolniona przez operatora Usuń. W C ++ jest to warunkiem wstępnym. Jeśli nie zwolnisz pamięci, pamięć pozostanie wybrana (zajęta), ale nie będzie w stanie go użyć. W tym przypadku stanie się "wyciek pamięci" (Wyciek pamięci).

W językach programowania Java C # nie jest potrzebny do zwolnienia pamięci po wybraniu. Jest on zaangażowany w "Collector Garbage".

Ogólne Usuń formularz operatora do samotnej zmiennej:

Usuń PTRAME;

gdzie pTRNAME. - Nazwa wskaźnika, dla której operator pamięci został wcześniej podświetlony. Po wykonaniu operatora usuwania operatora pTRNAME. Wskazuje dowolną sekcję pamięci, która nie jest zarezerwowana (dedykowana).

5. Przykłady rozwoju (nowy) i zwolnienie (usuń) dla wskazówek typów podstawowych

Przykłady pokazują wykorzystanie nowych i usuwania operatorów. Przykłady mają uproszczony widok.

Przykład 1. Wskaźnik do wpisywania int. Najprostszy przykład

// Wybierz operator pamięci Nowy int * p; // indeks na int p \u003d nowy int; // Wybierz pamięć dla wskaźnika * p \u003d 25; // Nagrywaj wartości w pamięci // Użyj pamięci przydzielonej dla wskaźnika int d; d \u003d * p; // d \u003d 25 // Zapewnij pamięć przydzieloną dla wskaźnika - upewnij się Usuń P;

Przykład 2. Wskaźnik do podwójnego typu

// Wybieranie pamięci dla wskaźnika do podwójnego Podwójny * pd \u003d null; Pd \u003d nowy podwójny; // Wybierz pamięć. Jeśli (pd! \u003d null) (* pd \u003d 10.89; // WARTOŚĆ WAZR podwójna d \u003d * pd; // d \u003d 10.89 - Użyj w programie // zwolnij pamięć Usuń PD; )
6. Co to jest "wyciek pamięci"?

« Wyciek pamięci"To jest, gdy pamięć dla zmiennej jest podkreślona nową instrukcją, a na końcu programu nie jest zwolniony przez operatora Usuń. W tym przypadku system w systemie pozostaje zajęty, chociaż nie ma potrzeby jego użycia, nie jest już, ponieważ program, który użył go od dawna zakończył pracę.

"Wyciek pamięci" jest typowym błędem programisty. Jeśli "wyciek pamięci" jest powtarzany wielokrotnie, to możliwa sytuacja, gdy będzie "zajęty" wszystkie dostępne pamięci w komputerze. Doprowadzi to do nieprzewidywalnych konsekwencji systemu operacyjnego.

7. Jak przydzielić pamięć przez nowego operatora z przechwyceniem krytycznej sytuacji, w której pamięć może się nie wyróżniać? Wyjątkowa sytuacja Bad_alloc. Przykład

Podczas korzystania z nowego operatora, możliwe jest sytuacja, gdy pamięć nie jest rozszerzona. Pamięć nie może wyróżniać się w następujących sytuacjach:

  • jeśli nie ma wolnej pamięci;
  • rozmiar wolnej pamięci jest mniejsza niż ta, która została określona w nowej instrukcji.

W tym przypadku wyjątkowa sytuacja jest bad_alloc. Program może przechwycić tę sytuację i odpowiednio przetworzyć.

Przykład. Przykład uwzględnia sytuację, gdy pamięć nie może wyróżniać nowego operatora. W takim przypadku podjęto próbę przydzielenia pamięci. Jeśli próba zakończy się sukcesem, kontynuuje prace programu. Jeśli próba zakończyła się awarią, a następnie wyjście z funkcji kodu -1.

Int main () ( // deklaruj tablicę wskaźników na płycie Float * ptarray; próbować ( // Spróbuj podświetlić pamięć dla 10 elementów pływaka typu ptarray \u003d nowy float; ) Catch (Bad_alloc BA) (Cout<< << endl; cout << ba.what() << endl; return -1; // Funkcja wyjścia } // Jeśli wszystko jest w porządku, użyj tablicy dla (int i \u003d 0; ja< 10; i++) ptrArray[i] = i * i + 3; int d = ptrArray; cout << d << endl; delete ptrArray; // zwolnij pamięć przydzieloną dla tablicy Powrót 0; )
8. Wybór pamięci dla zmiennej z jednoczesnym inicjalizacją. Całkowity kształt. Przykład

Nowy operator alokacji pamięci dla pojedynczej zmiennej umożliwia jednoczesną inicjalizację z wartością tej zmiennej.

Ogólnie rzecz biorąc, alokacja pamięci dla zmiennej z jednoczesną inicjalizacją jest

pTRNAME.\u003d Nowy typ ( wartość)
  • pTRNAME.- nazwa zmiennej wskaźnika, dla której przypisuje się pamięć;
  • rodzaj - Wpisz, do którego wskazuje wskaźnik pTRNAME. ;
  • wartość - Wartość zainstalowana dla wybranej sekcji pamięci (wartość przez oznakowanie).

Przykład. Wybór pamięci dla zmiennych o jednoczesnym inicjalizacji. Poniżej znajduje się główna () funkcja aplikacji konsoli. Zademonstrowana alokacja pamięci przy jednoczesnej inicjalizacji. Sytuacja jest również brana pod uwagę, gdy próba przydzielania pamięci jest zakończona awaria (sytuacja krytyczna Bad_alloc).

#Include "stdafx.h" #include Za pomocą przestrzeni nazw STD; Int main () ( // Wybieranie pamięci o jednoczesnej inicjalizacji Float * pf; int * pi; Char * PC; próbować ( // Spróbuj podświetlić pamięć dla zmiennych o jednoczesnej inicjalizacji PF \u003d Nowy pływak (3.88); // * pf \u003d 3,88 pi \u003d nowy int (250); // * pi \u003d 250 pc \u003d Nowy znak ("M"); // * PC \u003d "M") Catch (Bad_alloc BA) (Cout<< "Wyjątkowa sytuacja. Pamięć nie jest przydzielona" << endl; cout << ba.what() << endl; return -1; // Funkcja wyjścia } // Jeśli pamięć jest podświetlona, \u200b\u200bużycie PF, PI, wskaźniki PC Float f \u003d * pf; // f \u003d 3,88 int i \u003d * pi; // i \u003d 250; Char c; C \u003d * PC; // c \u003d "m" // Wyświetlanie zainicjowanych wartości Cout.<< "*pF = " << f<< endl; cout << "*pI = " << i << endl; cout << "*pC = " << c << endl; // Zapewnij pamięć przydzieloną dla wskaźników Usuń PF; Usuń PI; Usuń komputer; Powrót 0; )

Dzwon.

Są ci, którzy przeczytali tę wiadomość przed tobą.
Subskrybuj odbieranie artykułów świeżych.
E-mail
Nazwa
Nazwisko
Jak chcesz przeczytać dzwonek
Bez spamu