Ugrás a tartalomhoz

delete

A Wikiszótárból, a nyitott szótárból

Kiejtés

  • IPA: /dɪˈliːt/

Ige

delete (alapjelen, egyes szám harmadik személy deletes, folyamatos melléknévi igenév deleting, második és harmadik alakja deleted)

  1. (informatika) töröl

A delete kulcsszó C++-ban a dinamikusan foglalt memória felszabadítására szolgál. Amikor a new operátorral memóriát foglalunk a heapen, azt kézzel kell felszabadítani, különben memóriaszivárgás léphet fel.



1. Miért van szükség a delete kulcsszóra?

A stack memóriában lévő változók automatikusan felszabadulnak, amikor a függvény befejeződik:

void fuggveny() {
    int x = 5;  // Automatikusan törlődik a függvény végeztével
}

Ezzel szemben a heap memóriában lévő adatok nem szabadulnak fel automatikusan:

int* p = new int(10);  // Dinamikus memóriafoglalás
// Ha itt nem használunk `delete p;`, memóriaszivárgás történik!

Ha nem használjuk a delete-et, akkor a memória nem kerül vissza az operációs rendszerhez, ami idővel memóriahiányhoz vezethet.



2. Egyszerű delete használat

A delete operátort egyedi objektumok felszabadítására használjuk.

Példa: Dinamikus memória felszabadítása

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int(42);  // Egy `int` foglalása a heapen
    cout << "Érték: " << *ptr << endl;
    
    delete ptr;  // Felszabadítjuk a memóriát
    ptr = nullptr;  // Jó gyakorlat: érvénytelenítjük a mutatót

    return 0;
}

Fontos:
- A delete ptr; felszabadítja az int-hez tartozó memóriát. - A ptr = nullptr; megakadályozza, hogy a mutató egy felszabadított területre mutasson (dangling pointer elkerülése).



3. delete[] használata tömböknél

Ha egy dinamikus tömböt (new[]) foglalunk, akkor delete[]-et kell használni.

Helytelen használat (delete tömb esetén)

int* tomb = new int[5];  
delete tomb;  // HIBA! Csak az első elem szabadul fel

Ez memóriaszivárgást okozhat, mert a tömb többi eleme nem kerül felszabadításra!

Helyes használat (delete[])

int* tomb = new int[5];  
delete[] tomb;  // Helyesen felszabadítja a teljes tömböt
tomb = nullptr;

Miért van külön delete és delete[]?
- A delete egyetlen objektumot töröl. - A delete[] biztosítja, hogy a teljes tömb memóriája felszabaduljon.



4. Osztálypéldányok és delete

Amikor egy osztályt dinamikusan hozunk létre, a delete automatikusan meghívja az osztály destruktorát (~ClassName()).

Példa osztálypéldányok törlésére

#include <iostream>
using namespace std;

class Ember {
public:
    string nev;

    Ember(string n) { 
        nev = n; 
        cout << nev << " létrehozva!" << endl;
    }

    ~Ember() { 
        cout << nev << " törölve!" << endl; 
    }
};

int main() {
    Ember* p = new Ember("Anna");
    delete p;  // A destruktor automatikusan meghívódik
    return 0;
}

Kimenet:

Anna létrehozva!
Anna törölve!

Mi történik? - A new létrehoz egy Ember objektumot a heapen. - A delete p; felszabadítja a memóriát és meghívja a destruktort.



5. Tömbök és osztálypéldányok (delete[])

Ha egy osztálytömböt dinamikusan foglalunk, a delete[] hívja meg az összes objektum destruktorát.

Példa: Osztálypéldányok tömbjének felszabadítása

#include <iostream>
using namespace std;

class Ember {
public:
    Ember() { cout << "Létrejött egy ember!" << endl; }
    ~Ember() { cout << "Egy ember törölve!" << endl; }
};

int main() {
    Ember* emberek = new Ember[3];  // Három objektum a heapen

    delete[] emberek;  // Minden objektum destruktora meghívódik
    return 0;
}

Kimenet:

Létrejött egy ember!
Létrejött egy ember!
Létrejött egy ember!
Egy ember törölve!
Egy ember törölve!
Egy ember törölve!

6. delete és virtuális destruktorok

Ha egy osztályban öröklődés van, és az objektumot az alaposztály mutatóján keresztül töröljük, akkor a destruktor legyen virtuális!

Példa hibás törlésre (nincs virtual destruktor)

class Alap {
public:
    ~Alap() { cout << "Alap destruktor" << endl; }
};

class Szarmaztatott : public Alap {
public:
    ~Szarmaztatott() { cout << "Származtatott destruktor" << endl; }
};

int main() {
    Alap* obj = new Szarmaztatott();
    delete obj;  // Csak az Alap destruktora hívódik meg!
    return 0;
}

Kimenet:

Alap destruktor

Mi a baj? - Csak az alaposztály destruktora fut le, így a leszármazott objektum memóriaszivárgást okozhat.

Megoldás: Virtuális destruktor

class Alap {
public:
    virtual ~Alap() { cout << "Alap destruktor" << endl; }
};

class Szarmaztatott : public Alap {
public:
    ~Szarmaztatott() { cout << "Származtatott destruktor" << endl; }
};

int main() {
    Alap* obj = new Szarmaztatott();
    delete obj;  // Most mindkét destruktor lefut!
    return 0;
}

Kimenet:

Származtatott destruktor
Alap destruktor

Megoldás:
A virtuális destruktor (virtual ~Alap()) biztosítja, hogy az összes leszármazott osztály destruktora helyesen lefusson.



7. Gyakori hibák és megoldások

Hiba Probléma Megoldás
delete egy tömbre Csak az első elem szabadul fel Használj delete[]-et
delete[] egy objektumra Undefined behavior Használj delete-et
delete-et elfelejtjük Memóriaszivárgás Minden new után legyen delete
Dupla delete (delete ptr kétszer) Double delete hiba Használj ptr = nullptr; után
Öröklött osztály destruktora nem hívódik meg Memóriaszivárgás Használj virtuális destruktort



8. Összegzés

  • delete egyetlen dinamikusan foglalt objektumot töröl.
  • delete[] dinamikus tömböket töröl.
  • Mindig használd a delete után a nullptr-t, hogy elkerüld a dangling pointereket.
  • Virtuális destruktorok szükségesek, ha az objektumot polimorf módon törlöd (Alap* p = new Szarmaztatott();).

A helyes delete használat kulcsfontosságú a memóriakezelés és a stabil C++ programok szempontjából!