PR2ET8: Dünaamiline mälu 2

Labori materjal

Laboriülesanded

Selles laboris on üks ülesanne, mida laiendab 2 edasijõudnute ülesannet

Ülesanne: Faili lugemine kasutades dünaamilist mälu

Selle ülesande eesmärgiks on tutvuda kuidas lugeda teadmata pikkusega faile sedasi, et me kasutame täpselt nii palju mälu kui failis olevate andmete hoiustamiseks vaja on.

Andmefail

Andmefaili struktuur on järgnev:  <indeks> <perenimi> <eesnimi> <õppekava kood> <punktide arv>

  • Indeks (täisarv)
  • Ees- ja perenimi – erineva pikkusega sõned
  • Õppekava kood – 4-tähemärgi pikkune sõne
  • Punktide arv – kümnendmurd vahemikus 10,0 kuni 30,0,. Täpsuse 0,1.

Võid kasutada andmefailide loomiseks oma eelmise nädala laboriülesande lahendust. Testimiseks on antud siiski kindlad failid, et saaksid oma väljundit võrrelda.

Andmefailid mille väljundi näited on ka testimine osas: https://blue.pri.ee/ttu/files/iax0584/andmefailid/8_scholarship_data.zip

Nõuded
  • Loe teadmata pikkusega andmefaili sisu mällu
    • Lugemiseks kasuta realloc() funktsiooni, laiendades mäluala suurust jooksvalt lugemise käigus.
    • Andmed salvesta dünaamiliselt loodud struktuurimassiivi
    • Lugemise lõpuks peab küsitud mälumaht olema täpselt nii suur kui on vaja failis olevate andmete hoiustamiseks.
    • Faili tohib vaid ühel korral lugeda (korduv lugemine keelatud! Ka lihtsalt reavahetuste arvu lugemine ei ole lubatud!)
    • Arvesta, et faili pikkus võib muutuda! St faili pikkus selgub lugemise käigus!
  • Kõik muutuva pikkusega sõned tuleb mälus hoida täpse pikkusega.
    • Lugemise ajal kasuta staatilist puhvrit, struktuuris hoidmiseks kasuta dünaamilist mälu!
  • Failis on stipendiumile kandideerivate tudengite loetelu. Stipendiumi saavad:
    • Igast järgnevast erialast kuni 7 kõige kõrgema punktisummaga tudengit: IACB, EARB ja MVEB.
  • Kuva stipendiumi saajate nimekiri ning näita mitu tudengit igalt erialalt stipendiumi sai.
  • Veendu, et programm ei tekita mälulekkeid!
Andmestruktuur ülesandele

Selles ülesandes läheme üle dünaamilisele mälule struktuuri liikmete hulgas mille pikkus on muutuv (sõned ja teised massiivid) – see säästab meil mälu ja suurendab paindlikkust. Struktuur võtab järgneva kuju:

Märkused:

  • Soovi korral võid nimetusi endale sobilikumaks muuta
  • fName ja lName on nüüd viidad, mis vajavad dünaamilist mälu enne kui nendesse midagi salvestada saab – seda kuna nime pikkus on muutuv inimeselt inimesele.
  • Õppekava koodi massiiv on staatiline sest see on alati täpselt sama pikk – dünaamiline mälu siin oleks raiskav.
  • Üksikud täisarvud, murdarvud jne jäävad samuti staatiliseks – jällegi, dünaamiline mälu siin teeks programmi põhjendamatult aeglasemaks ja keerukamaks.
Soovituslik loetelu funktsioonidest

NB! Funktsioonide tegelik kuju sõltub kuidas otsustad ülesannet lahendada ja struktureerida.

Minimaalselt on sul vaja kolme funktsiooni:

  • Andmete lugemise funktsioon failist (vali välja järgmisest peatükist).
  • Vastuste väljastamise funktsiooni.
  • Andmete vabastamise funktsiooni

Soovituslikud funktsioonid enda elu lihtsamaks tegemiseks

  • qsordi võrdlusfunktsioon
  • Ühe tudengi andmete printimise funktsioon (kasulik kui prindid tudengi andmeid, kes stipendiumi saab.
  • Kaitsva programmeerimisstiili jaoks kulub ära ka slaididel näidatud vabastamisfunktsioon

Lugemise kontrollimiseks võib olla mõistlik luua ka funktsioon, mis trükib kõigi tudengite andmed välja mis failist kätte saadi. See aga pole ülesande osa.

Funktsioon andmete lugemiseks

Sel korral võtab andmete lugemise funktsioon veidi teistsuguse kuju.  Funktsioonist on meil vaja saada kätte 2 uut väärtust – mälu asukoht ja ridade arv. Pakun välja kolm võimalikku lahendust – vali endale meelepärane!

Esimene variant tagastab ridade arvu ning edastab mälu asukoha kasutades topeltviita :

Teine variant tagastab mälu asukoha ning edastab ridade arvu kasutades viita:

Pakun välja ka kolmanda võimaluse. Selle eelis on võimalus funktsioonist tagastada kood, mida saab tõlgendada kas eduka või ebaõnnestunud lugemisega. Koode võib olla enam kui soovid erinevate vigade detaile edastada.

Testimine

Esimeses näites kasutame pikemat andmefaili, kus kõik loetelud said täis.

Teises näites on andmefail lühem.

Edasijõudnute ülesanne 1: Optimaalne mäluhõive

Selles ülesandes muudame oma dünaamilise mälu hõivamise mõistlikumaks kasutades optimaalsemat mälu laiendamise strateegiat.

Nõuded
  • Muuda oma faili lugemist sedasi, et lugemisek kasutaksid (n * 2) strateegiat
    • St iga kord kui küsitud mälumaht saab otsa, laiendatakse mäluala 2x võrreldes olemasolevaga
  • Alustamiseks vali n mis on suurem kui 1 (vali siiski vähemalt 3x väiksem kui pikima faili pikkus

Edasijõudnute ülesanne 2: ümbris-struktuur

Selles ülesandes muudame oma koodi veelgi loetavamaks ja seotumaks, pannes oma andmestruktuuri ja selle omadused ühte ümbritsevasse struktuuri.

Nõuded
  • Pane oma struktuurimassiiv teise struktuuri ehk ümbrise sisse (wrapper struct),
  • Ümbrises peaks olema 3 muutujat – viide struktuurile, struktuuri suurus ja struktuuri kasutatud liikmete arv.
  • Muuda oma funktsioonide parameetreid nii, et nüüd need kasutaksid uut vastloodud ümbrisstruktuuri.
  • NB! Mõtle läbi mis funktsiooni on mõistlik viit ümbrisele anda, millisesse pole seda mõtet teha!

Vihje: Kuna nüüd on iga välja poole pöördumisel vaja ümbrisstrukuturist valida välja õige liige, siis võib loetavuse huvides olla see mõistlik “lahti pakkida” eraldi muutujasse vastava funktsiooni või tsükli sees. Näiteks

Pärast seda tundi peaksid

  • teadma erinevaid võimalusi kuidas struktureerida ja lugeda faile mille pikkus võib erineda
  • oskama dünaamiliselt oma massiivide suurust muuta
  • oskama lugeda faile dünaamilist mälu kasutades jooksvalt ja täpselt
  • teadma kõiki võimalike realloci tagastuste võimalus
  • teadma kahte laiendamise strateegiat (n + 1) ja (n * 2) ning oskama neid kahte võrrelda
  • oskama struktuuri liikmetele mälu küsida
  • teadma ja oskama rakendada ohutu programmeerimise tehnikat mälu vabastamisel.
  • teadma kõiki samme mida strdup() funktsioon taustal teeb

Täiendav materjal