Teen (yritän) C-kielellä ohjelmaa, jossa käyttäjän antama teksti muutetaan morsekoodiksi. Maksimi sanojen määrä on 50. Miten voisin varata taulukon dynaamisesti, ettei käyttäjän tarvitse laskea, montako merkkiä aikoo syöttää?
Dynaaminen muistin varaus C
ongelmainen
4776
0Äänestä
Muut lukivat myös
Odottaa vastausta
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 4
Vanhimmat
Jotain vaikka täällä:
http://www.cs.uku.fi/kurssit/okb2003/ch03s05.html
paljon suuremmalle taulukolle kun mitä kuvittelet kenen syöttävän
char merkit[32000];
(tai char* merkit;
merkit=malloc(32000);)
ja testaat jokaista merkkiä kunnes viimeinen on NULL (nolla).
Voit tietysti myös testata syöttöä merkkikohtaisesti ja varata sille tarkasti tarvittavan muistin, mutta tuntuu siltä että tämä menee sinulle vaikeaksi.
Morse-aakkoset ovat binäärimuotoa (pitkä-lyhyt, ainoastan kaksi arvoa, 0-1) eli tehokkain tapa implementoida niitä ovat binary tree-rakenteen muodossa (klassinen esimerkki). Vaikka nykyaikaisillä koneilla nopeusero ei näy niin oma osaaminen kuitenkin lisääntyy (voidaan hyödyntää vaativimmissa projekteissa). Esim. käyttöjärjestelmän tiedostorakenne on toteutettu binary tree rakenteella (ensimmäinen kirjain pienempi kuin "l" mene vasemmalle, muuten oikealle. Toinen kirjain pienempi kuin "l" mene vasemmalle, muuten oikealle jne). Haun tehokkuus kasvaa ekponentiaalisesti, eli jos sinulla 65000 tiedostoa löydät oikean 16 laskentaoperaatiolla (jos etsit niitä yksitellen tarvitset 65000 laskentaoperaatiota). Yhdellä lisäoperaatiolla löydät 130000 tiedostoa, kahdella 260000 jne.
on että et varaa suuria puskureita muuta kuin aliohjelmissa. Tällöin niiden elinikä (scope) on yhtä pitkä kun se aika jota viivyt aliohjelmassa, heti kun poistut muisti (ja sen sisältö vapautuu jos olet määritellyt taulukon:
void aliohjelma(void)
{
char taulukko1[32000]; //käytettävissä ennen return, sen jälkeen muistialue (ja sen sisältö) unohdettu.
char* taulukko2=malloc(sizeof(char)*32000); //Tositarkoituksella, ei unohdetaan niin helposti
// nyt voit käyttää samantyyppisiä lausekkeita sekä taulukko1 että taulukko2 kohdalla! Nyt mennään pois!
return;
}
Mitä tapahtui?
Taulukko1:n varaama muistitila häipyi saman tien. Taulukko2 (mallocilla allokoituna (malloc tarkoittaa memory allocation, eli muistin varausta)) ei poistu minnekään, vaikka et enä tiedä missä se sijaitse (siihen tarvitset sen muistiosoitteen, "taulukko2"-muuttujan sisältöä, mutta sitä et ole kertonut ulkomaailmalle (siis kutsuvalle ohjelmalle)!
Eli joka kerta kun kutsut aliohjelmaa se varaa sinulle 32k muistikimpaleen lisää ja vartioi sitä niin mustasukkaisesti että kukaan muu ei koskaan pääse siihen käsiksi.
Tämä ei ehkä kuullosta niin pahalta, mutta ajattele tilannetta että aliohjelmasi kutsutaan loopista 100 000 kertoja! tai että käyttäjä käyttää ohjelmasi tuntikaupalla, aina välillä kutsuen sun aliohjelmasi.
Tämä ilmiö kulkee nimellä "memory leak", "muistivuoto" ja se om ainoastaan sinun aiheuttama ja täysin sinun vastuullasi!
Hyvin suunniteltu ohjelma (joka esim. tarkistaa saiko pyytämänsä muistia, miksi ei, tekee hallitun pakkolaskun jne) pärjää paremmin. Prosessori inisee paljon ennen kuin varsinaiset ilmiöt tulevat esille.
Eli jos käytät muistialue = malloc(32000);
sinun on käytettävä free(muistialue);
ennen kuin "muistialue" on "unohdettu" ("out of scope")
Jos käytät määritelmiä tyyliin:
char taulukko1[32000];
sinun ei tarvitse välittää, ne tuhoutuvar heti lun poistutaan aliohjelmasta.
..tyhmä kun olen. Kiitos noista vastauksista, siksi kyselinkin, koska en haluaisi turhaa varata muistia. Olisko teillä vielä intoa neuvoa, mikä on rakenteisen tiedon käsittely idea eli olen tehnyt tällaista:
struct morset
{
char *kirjain;
char *morse;
}taulukkoKoodit[TAULUKKO_KOKO]=
{
{ 'a', ".-"} ,...
En ymmärrä, koska noita osoittimia käytetään..Yritän siis saada käyttäjän tekstin morsekoodiksi (pisteet viivat).