Jak to jest ze zwalnianiem pamięci dynamicznie zaalokowanej?

Odpowiedz Nowy wątek
2014-11-12 20:46
0

Cześć,

Mam taki przykładowy kod:

#include <iostream>

using namespace std;

struct ABC
{
    int a, b ,c;
    ABC()
    {
        cout << "Konstruktor ABC" << endl ;   
    }
    ~ABC()
    {
        cout << "Destruktor ABC" << endl ;   
    }
};

int main()
{ 
    {
     ABC* ptr = new ABC();

     cout << " ptr = " << ptr << endl ;
    }

    ABC* ptr2 = new ABC();
    cout << " ptr2 = " << ptr2 << endl ;
}

..i output:

Konstruktor ABC
 ptr = 0x170f010
Konstruktor ABC
 ptr2 = 0x170f030

Chciałem zapytać, czy nie powinien mieć miejsce teraz wyciek pamięci, jeśli nie ma delete?
Mógłby ktoś jakimś słowem wyjaśnienia wspomóc?

Kompilator GCC 4.9

Dzięki z góry za pomoc!

Pozostało 580 znaków

2014-11-12 20:54
2

Ma, ale i tak zaraz program się zakończy, więc wsio jedno (oprócz złego nawyku programistycznego). Co innego gdyby Twój program działał dłuższy okres czasu i co chwilę wycieka (i to więcej niż 1 malutki obiekcik), to wtedy jest szansa, że kiedyś ta pamięć się skończy.

Nawet jak jeden malutki będzie wyciekał raz na kilka sekund - to po paru dniach ... - _13th_Dragon 2014-11-12 20:58
jezeli przyjac ze wycieka 20kB co 4 sekundy to po calym dniu wycieknie ± 430 MB, dzisiejsze komputery maja przynajmniej 8 GB pamieci, wiec zalozmy ze program ktory ten super program bedzie uruchomiony bedzie mial 32 GB (pamiec jest tania wiec mozna tak zalozyc) Powiedzmy ze wszystkie inne programy biora 8 GB (a co) wiec zostaje 24 GB. 24000 / 430 = 55 dni. Jezu ale mi sie pracowac dzisiaj nie chce skoro licze takie rzeczy :D - fasadin 2014-11-13 09:11
Zapominasz o defragmentacji, przy takich ucieczkach mimo że fizycznie nadal będzie dużo pamięci ale skończy się pula adresów. - _13th_Dragon 2014-11-13 12:19

Pozostało 580 znaków

2014-11-12 20:58
0

Ale sam brak wyrażenia delete ptr; nie zwróci błędu?
Dopiero będzie error jak cała pamięć się skończy?
Twonek - przecież kompilator chyba powinien informować o tym, że wycieka pamięć, bez względu na to ile dalej program ma pracować?

Pozostało 580 znaków

2014-11-12 20:59
3

Kompilator nie jest w stanie tego sprawdzić.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-11-12 21:06
0

Skąd kompilator ma o tym wiedzieć. Może być tak, że kod do zwalniania masz w instrukcji warunkowej:

if (mam_dobry_humor()) delete ptr;

i w tym momencie nikt nie wie czy zawsze ta pamięć będzie zwalniana, czy czasami czy nigdy.

No niby są te narzędzia do statycznej analizy kodu, które potrafią takie wycieki wyłapywać, ale też nie są 100% skuteczne.

Pozostało 580 znaków

2014-11-12 21:07

Valgrind jest w stanie pomóc.

Czasem wyciek polega np na wrzuceniu wskaźnika do obiektu do jakiejś globalnej mapy obiektów i pozostawieniu go tam na całą wieczność. Niby dalej można się dobrać do obiektu, ale skoro jest on nieużywany to jest wyciekiem. Z tego względu w każdym języku może dojść do wycieku, bo ani kompilator ani interpreter czy maszyna wirtualna nie są w stanie stwierdzić kiedy osiągalny obiekt staje się całkowicie niepotrzebny. W każdym języku trzeba mieć na uwadze wycieki pamięci, ale w C++ jest z nimi najwięcej kopaniny, bo nie ma pomocnej ręki Garbage Collectora (a nawet jeśli ktoś dorzuci, to nie jest zintegrowany z językiem).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 2x, ostatnio: Wibowit, 2014-11-12 21:09

Pozostało 580 znaków

2014-11-12 21:36
kq
1

Ogólnie złym nawykiem¹ jest jawne używanie new i delete. Masz std::unique_ptr i std::shared_ptr (i odpowiednio std::make_unique i std::make_shared), masz kontenery typu std::vector. Używaj ich, jest łatwiej, bezpieczniej i przejrzyściej.

¹ Chyba, że piszesz własny alokator czy coś w tym stylu


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0