Elektroda.pl
Elektroda.pl
X
Arrow Multisolution Day
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

C++ - Zajmowanie i zwalnianie pamięci

MrOwocowy 27 Lip 2014 18:09 1353 6
  • #1 27 Lip 2014 18:09
    MrOwocowy
    Poziom 8  

    Cześć !

    Wciąż jestem początkujący jeżeli chodzi o programowanie, ale co nieco już potrafię i moje przykładowe aplikacje robią się coraz bardziej rozbudowane, co za tym idzie zajmują więcej pamięci. Chciałbym dokładniej się dowiedzieć kiedy obiekty tworzone przeze mnie są usuwane, czyli kiedy dokładnie pamięć się zwalnia.

    Chciałbym zacząć od funkcji. Z tego co wyczytałem to obiekty tworzone w funkcji są automatycznie usuwane od razu po jej zakończeniu. Czy więc jest sens używania w funkcji operatorów new i delete do usuwania obiektów skoro i tak zaraz będą usunięte ? A jeżeli tak czy po użyciu operatora new te obiekty i tak zostanę usunięte, bo z tego co mi wiadomo to obiekty stworzone operatorem new istnieją aż do momentu usunięcia ich operatorem delete.

    Czy opłaca się tworzyć obiekty w klasie przy użyciu operatora new ? I kiedy je kasować ? ( W destruktorze ? )

    Wciąż nie mogę zrozumieć do czego przydaje się operator new. Jedyne co przychodzi mi do głowy to możliwość stworzenia tablicy obiektów już w trakcie pracy programu.

    Tak naprawdę większość z tego o co pytam jest w mojej książce, ale jest to poruzrzucane po różnych działach. Chciałbym, aby ktoś opisał mi to wszystko w jednym poście, abym mógł z dobrze zrozumieć.

    Dziękuję !

    0 6
  • Arrow Multisolution Day
  • Pomocny post
    #2 27 Lip 2014 22:12
    krru
    Poziom 32  

    Źle wyczytałeś - automatyczne usuwanie przy wyjściu z funkcji są jedynie obiekty allokowane automatycznie czyli np. zmienne lokalne funkcji.

    To będzie automatycznie utworzone i usunięte:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    A tutaj automatycznie będzie utworzony tylko wskaźnik, po wyjściu z funkcji masz wyciek pamięci bo utworzony obiekt jest osierocony i już nic na niego nie wskazuje, więc jest już niedostępny
    Kod: cpp
    Zaloguj się, aby zobaczyć kod



    Obiekty allkowane operatorem new muszą być zawsze usunięte operatorem delete - każde new ma mieć opowiadający mu operator delete. Teoretycznie, po zakończeniu programu system zwalnia wszystko co w programie użyto, jednak poleganie na tym to zła praktyka, bo np. w przyszlości to co teraz masz jako program będziesz chciał użyć jako funkcję w większym programie i już masz wycieki.

    Dynamiczne powoływanie obiektów ma dwa główne zastosowania
    1. Z góry trudno przewidzieć maksymalną liczbę obiektów.
    2. Może to trochę mniej kwestia allokacji a bardziej wskaźników - to bardziej skomplikowane struktury danych, typu listy, drzewa, grafy itp. - łatwiej wtedy poprzestawiać wskaźniki niż kopiować obiekty. Jak już się używa wskaźników to wygodnie i czytalnie jest allokować.

    0
  • Arrow Multisolution Day
  • #3 27 Lip 2014 23:23
    MrOwocowy
    Poziom 8  

    A więc gdy mam jakąś funkcję, w której potrzebuję stworzyć jakiś obiekt to jest jakaś spora różnica czy zrobię to przy użyciu operatora new a na koniec tej funkcji użyje delete czy "po staremu" bez użycia tych operatorów ?

    Za kilka dni, gdy będę miał dostęp do własnego komputera i mam zamiar stworzyć własną klasę. Będę potrzebował 2 tablice typu char, jedna musi być 4 elementowa a druga 7 elementowa. Powinienem stworzyć takie tablicę operatorem new i następnie usunąć je w destruktorze czy zrobić to po prostu bez operatora new ? Przyszło mi też na myśl stworzenie jednej tablicy np. 10 elementowej i w momencie uzupełniana jej w różnych funkcjach dodać jeden argument więcej, który będzie ograniczał możliwość wpisywania do niej nie dalej niż 4 element bądź 7 element.

    0
  • Pomocny post
    #4 27 Lip 2014 23:37
    alagner
    Poziom 25  

    Raz, jeśli wiesz, że potrzebujesz stałego rozmiaru tablic, to odpuść sobie new i delete.
    Dwa, zrób dwie osobne tablice żeby kod był czytelny.

    Jeśli już musisz optymalizować na poziomie kodu to w fazie końcowej projektu. A na etapie nauki - nie rób tego, dbaj o czystość i czytelność tego co napiszesz. Nie używaj bit shiftów zamiast normalnej arytmetyki itd.

    Chyba, że piszesz na mikrokontroler z 64b RAMu. Ale nawet wtedy, najpierw czytelnie, a potem optymalnie, a jeżeli nie wisi nad Tobą dział handlowy krzyczący o cenie większej ilości pamięci, to po prostu zmień platformę sprzętową na bardziej odpowiednią.

    Pozdrawiam

    0
  • Pomocny post
    #5 27 Lip 2014 23:41
    aso824
    Poziom 13  

    Jeżeli mówiąc "po staremu" masz na myśli statyczne alokowanie, to jest spora różnica.

    To jest alokowanie statyczne, czyli po wyjściu z zakresu funkcji obiekt jest automatycznie usuwany:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Lecz jeżeli masz funkcję która ma przetworzyć nieokreśloną z góry (w czasie pisania programu) ilość danych, to używasz dynamicznej alokacji:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Z reguły jeżeli wiesz dokładnie jakie mają być obiekty - alokujesz je normalnie. Dynamiczny przykład podałem powyżej.

    Jest jednak ważna rzecz - obiekty alokowane statycznie są przechowywane w stosie, a dynamiczne - w stercie. Jeżeli potrzebujesz przechować duże obiekty to i tak rób je dynamicznie, trafią do sterty, która jest większa (uproszczenie).

    0
  • #6 28 Lip 2014 10:43
    MrOwocowy
    Poziom 8  

    Jeżeli dobrze pamiętam to wszystkie obiekty jak i ich tablice będą miały określony rozmiar i nic nowego w czasie trwania programu mi nie będzie potrzebne, czyli postaram się alokować je statycznie. Funkcje w moim programie to przede wszystkim wysyłanie tablic przez port COM.

    Dziękuję za pomoc.

    @EDIT

    Gdyby jednak ktoś miał jeszcze coś do dodania co mogłoby mi pomóc to proszę o odpowiedź w tym temacie.

    0
  • #7 01 Sie 2014 22:36
    BeginEnd
    Poziom 14  

    Sporo nauki przed tobą jeszcze. Po pierwsze musisz wiedzieć jaka jest różnica między stosem (stack) a stertą (heap). Jeśli tego sobie nie uświadomisz to trudno ci będzie pojąć po jakiego czorta stworzyli new oraz delete.

    Na twoim miejscu najpierw zająłbym się starym dobrym C oraz funkcjami malloc() oraz free(). Mówiąc w bardzo dużym uproszczeniu new jest odpowiednikiem malloc() (włściwie to calloc() ) a delete jest odpowiednikiem free(). Ale to w dużym uproszczeniu.

    Co dla Ciebie mogę poradzić prześledzenie działania poniższego programu.
    W C++ krytycznie ważne jest abyś wiedział (rano, wieczór, we dnie i o północy wybudzony ze snu) kiedy alokowana jest pamięć, kiedy jest zwalniana i kiedy jaki rodzaj konstruktora jest wywoływany. Bez tego radzę się nie brać za programowanie obiektowe w C++ i pozostać przy C który jest znacznie przyjemniejszy dla początkującego programisty.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0