Ugrás a tartalomhoz

dinamikus tömb

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

Kiejtés

  • IPA: [ ˈdinɒmikuʃtømb]

Főnév

dinamikus tömb

  1. (matematika)

Fordítások



A dinamikus tömb (dynamic array) C++-ban egy olyan adattípus, amely lehetővé teszi a tömb méretének futásidejű változtatását. Ez eltér a hagyományos C-stílusú tömböktől, amelyeknél a méretet fordítási időben kell meghatározni. A dinamikus tömb előnye, hogy rugalmasan alkalmazkodik a program futása közben felmerülő adatmennyiséghez, hátránya viszont, hogy bonyolultabb memória-kezelést igényel.



1. Statikus és dinamikus tömb közötti különbségek

A statikus és dinamikus tömb közötti fő különbség a memóriafoglalás módjában rejlik:

  • Statikus tömb: A méretét fordítási időben meg kell határozni, és a memóriafoglalás a stack-en történik.
  • Dinamikus tömb: A méret futásidőben határozható meg, és a memória a heap-en kerül lefoglalásra.

Statikus tömb példa:

#include <iostream>
using namespace std;

int main() {
    int tomb[5];  // 5 elemű statikus tömb
    for (int i = 0; i < 5; i++) {
        tomb[i] = i * 10;
    }

    for (int i = 0; i < 5; i++) {
        cout << tomb[i] << " ";
    }

    return 0;
}

Dinamikus tömb példa:

#include <iostream>
using namespace std;

int main() {
    int meret;
    cout << "Add meg a tömb méretét: ";
    cin >> meret;

    int* tomb = new int[meret];  // Dinamikus memóriafoglalás

    for (int i = 0; i < meret; i++) {
        tomb[i] = i * 10;
    }

    for (int i = 0; i < meret; i++) {
        cout << tomb[i] << " ";
    }

    delete[] tomb;  // Memória felszabadítása

    return 0;
}

2. Memóriafoglalás és felszabadítás

A dinamikus tömbök létrehozása a new kulcsszóval történik, amely a heap memóriából foglal helyet. Fontos, hogy minden dinamikusan lefoglalt memóriaterületet felszabadítsunk a delete[] kulcsszóval, különben memória-szivárgás léphet fel.

Memóriafoglalás:

int* tomb = new int[10];  // 10 elemű dinamikus tömb létrehozása

Memória felszabadítása:

delete[] tomb;

Ha nem használjuk a delete[]-t, akkor a program leállása után a memória nem szabadul fel automatikusan, ami memória-szivárgást okozhat, különösen hosszú ideig futó programok esetén.



3. Dinamikus tömb méretének módosítása

C++-ban a dinamikus tömb mérete közvetlenül nem módosítható. Ha nagyobb vagy kisebb tömbre van szükség, új memóriaterületet kell foglalni, az adatokat át kell másolni, majd a régi memóriát felszabadítani.

Méret módosításának példája:

#include <iostream>
using namespace std;

int main() {
    int meret = 5;
    int* tomb = new int[meret];

    // Eredeti tömb feltöltése
    for (int i = 0; i < meret; i++) {
        tomb[i] = i * 10;
    }

    // Új méret meghatározása
    int ujMeret = 10;
    int* ujTomb = new int[ujMeret];

    // Adatok átmásolása
    for (int i = 0; i < meret; i++) {
        ujTomb[i] = tomb[i];
    }

    // Régi tömb felszabadítása
    delete[] tomb;

    // Az új tömb használata
    tomb = ujTomb;

    // Új elemek inicializálása
    for (int i = meret; i < ujMeret; i++) {
        tomb[i] = i * 10;
    }

    // Kiíratás
    for (int i = 0; i < ujMeret; i++) {
        cout << tomb[i] << " ";
    }

    delete[] tomb;
    return 0;
}

4. Dinamikus tömb használata függvényekkel

Dinamikus tömböt függvények paramétereként is átadhatunk, általában pointer formájában.

Függvényes példa:

#include <iostream>
using namespace std;

void tombKiir(int* tomb, int meret) {
    for (int i = 0; i < meret; i++) {
        cout << tomb[i] << " ";
    }
    cout << endl;
}

int main() {
    int meret = 5;
    int* tomb = new int[meret];

    for (int i = 0; i < meret; i++) {
        tomb[i] = i * 10;
    }

    tombKiir(tomb, meret);

    delete[] tomb;
    return 0;
}

5. A std::vector használata dinamikus tömb helyett

Bár a C++ lehetővé teszi a nyers mutatókkal való dinamikus memória-kezelést, a std::vector használata sokkal biztonságosabb és kényelmesebb. Az std::vector automatikusan kezeli a memóriát, és lehetővé teszi a méret dinamikus módosítását anélkül, hogy manuálisan kellene foglalkozni a memóriafoglalással és felszabadítással.

std::vector példa:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec;

    // Elemek hozzáadása
    for (int i = 0; i < 10; i++) {
        vec.push_back(i * 10);
    }

    // Elemek kiíratása
    for (int i = 0; i < vec.size(); i++) {
        cout << vec[i] << " ";
    }

    return 0;
}

Miért jobb a vector? - Automatikusan kezeli a memóriafoglalást és felszabadítást. - Könnyen módosítható a mérete (push_back, resize). - Biztonságosabb, mivel elkerüli a mutatók hibáit. - Kényelmesebb iterálási lehetőségeket biztosít (range-based for ciklus).



6. Lehetséges hibák és elkerülésük

Memória-szivárgás

Ha elfelejtjük a delete[] használatát, a program a lefoglalt memóriát nem adja vissza a rendszernek.

Hibás példa:

int* tomb = new int[100];
// ... tömb használata
// Nincs delete[] -> memória-szivárgás!

Megoldás:

delete[] tomb;

Nullpointer használata

Ha egy mutató már felszabadított memóriára mutat, és megpróbáljuk használni, az undefined behavior-t eredményezhet.

Hibás példa:

int* tomb = new int[10];
delete[] tomb;
cout << tomb[0];  // Hibás, mert a memória már felszabadult!

Megoldás:

delete[] tomb;
tomb = nullptr;  // A felszabadítás után a mutatót nullára állítjuk.

Indexelési hiba (buffer overflow)

Ha a tömb határain kívüli elemet próbálunk elérni, a viselkedés nem meghatározott.

Hibás példa:

int* tomb = new int[5];
cout << tomb[10];  // Hibás, mivel csak 5 elem van lefoglalva!

Megoldás: Minden indexelésnél ellenőrizzük a határokat.



7. Összegzés

A dinamikus tömbök C++-ban hasznos eszközök, ha változó méretű adattárolásra van szükség, de nagy odafigyelést igényelnek a memória kezelése terén. A modern C++-ban a std::vector erősen ajánlott alternatíva, mivel automatikusan kezeli a memóriát, biztonságosabb és könnyebben használható. A megfelelő memóriafelszabadítás, a nullpointer-ellenőrzés és a határérték-ellenőrzés elengedhetetlen a hibák elkerüléséhez