Labor, 8. hét: dinamikus tömbök I.
Pohl László, Czirkos Zoltán · 2025.10.14.
Dinamikus tömbök létrehozása és kezelése.
A mai óra célja kettős. Egyrészről a dinamikus memóriakezeléssel foglalkozunk. Másrészről újra elővesszük kicsit a sztringeket (karaktertömböket).
Felkészülés a laborra:
- Az dinamikus memóriakezelésről szóló előadás anyagának megértése.
- A pointerekről és cím szerinti paraméterátadásról szóló gyakorlat átismétlése.
Írj programot, amely megkérdezi a felhasználótól, hány darab valós számot olvasson be; aztán elvégzi a számok beolvasását is egy dinamikusan foglalt tömbbe, és végül kiírja őket fordított sorrendben!
Tipp
Ahhoz, hogy ez akárhány darab számra működjön – ne korlátozza a beolvasható számok darabszámát
se egy tömb mérete, se a verem mérete –, dinamikus memóriakezelést kell használni. Emlékezz vissza
az előadásra: dinamikus memória a malloc() függvénnyel foglalható, amely visszaadja
a lefoglalt terület kezdőcímét. Ez tetszőleges típusú pointerré konvertálható, amilyen tömbelemeket
szeretnénk. Ha már nincs a memóriaterületre szükségünk, akkor a free() függvénnyel
kell felszabadítani azt. A foglalást nyilván azután tudjuk megtenni, hogy a felhasználó megmondta,
hány darab számot szeretne megadni.
A nagy házihoz adunk segédletként egy Debugmalloc nevű programot, amely a memóriakezelési hibák egy részét képes felfedezni. Erről bővebb leírást a Segédlet/Nagy házi menüpont alatt találsz: Debugmalloc. Ez a laborfeladat ennek az eszköznek a kipróbálása.
- Hozz létre egy projektet a szokásos módon a Code::Blocksban (File, New project stb.)
- Töltsd le a következő fájlt: debugmalloc.h.
Másold be a projekted mappájába, a main.c fájl mellé:
- Add hozzá a fájlt a projektedhez. Ehhez előbb kattints jobb gombbal a projekt nevére
a management ablakban:
- Aztán válaszd ki a fájlt, és kattints az okéra! Ellenőrizd, hogy tényleg be fog-e
kerülni a programba (Debug és Release be van-e jelölve):
- Végül ehhez kell jutnod:
Ha kész vagy, a helló világ programod írd felül az alábbi forráskóddal! Ez kettő memóriakezelési hibát tartalmaz. Látod, melyek ezek? Ha igen, akkor se javítsd még ki őket egyelőre!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debugmalloc.h"
int main(void) {
char txt[] = "hello";
char *p = malloc(strlen(txt) * sizeof(char));
strcpy(p, txt);
printf("TXT: %s\n", p);
return 0;
}
Futtasd le a programot, és figyeld meg a Debugmalloc hibaüzeneteit! Javítsd ki a hibákat!
A debugmalloc használata a házi feladatnál követelmény, ezért szokj hozzá laboron is, hogy minden dinamikus memóriakezelést igénylő feladatnál használd a továbbiakban! Sok, másként nehezen fellelhető hiba megtalálásában segít.
Hogy nézne ki az előző program, ha nem lehetne előre tudni, hány darab szám lesz? Vagyis ha nem előre adott hosszúságú sorozatot, hanem végjeles sorozatot (pl. utolsó szám után -1) kellene beolvasni? Írd meg így is a programot, minden új számnál megnyújtva a tömböt!
Tipp
Ha nem tudjuk előre, hány elem lesz, nem tudjuk előre lefoglalni nekik a memóriaterületet. Ezért jobb híján, legalábbis jelenlegi tudásunk szerint, kénytelenek vagyunk minden szám beolvasása után megnyújtani a tömböt. Ennek lépései:
- Új tömb foglalása.
- Meglévő számok átmásolása.
- Régi tömb felszabadítása.
- Új szám sor végéhez fűzése.
Ne feledd, a pointerek tetszőlegesen beállíthatók bármelyik dinamikusan foglalt tömbre! A lényeg, hogy egy foglalt terület címét sose veszítsük el – ha elveszítjük, sehogy nem fogjuk többé elérni az ott tárolt adatokat, és felszabadítani sem tudjuk már.
A sztringet sor végéig olvasó gets() kapcsán felmerül, hogy egy teljes sornyi szöveg beolvasása egy
„tyúk vagy tojás” probléma elé állít minket. Amíg nem foglaltuk le a tömböt, nem tudjuk beolvasni a szöveget;
viszont amíg nem olvastuk be a szöveget, nem tudjuk, milyen hosszú lesz, és így nem tudjuk lefoglalni a tömböt.
Hasonlóképp oldható meg ez a probléma, mint ahogyan azt az előbb, a végjeles sor beolvasásánál láttuk: a tömb most nem számokat, hanem karaktereket tartalmaz, a végjel pedig nem a -1, hanem az újsor karakter. Egy dologra kell csak figyelni: vajon mit tartalmaz a tömb, ha a sztring teljesen üres? Hány elemű ilyenkor a tömb?
Olvass be egy tetszőlegesen hosszú sort, és írd ki azt újra!
Ha elkészültél, folytasd a feladatgyűjtemény ehhez a témakörhöz kapcsolódó feladataival!