C kieli ja taulukot.

Saku-foorumi » Vapaa sana » Viestit 2004 » Viestit 09/2004 asti » C kieli ja taulukot. « Edellinen Seuraava »

Kirjoittaja Viesti
 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 8.05:   
Koska isot tähän tyyliin varatut taulukot ei ole suotavia
(kuulemma) eikä toimi kaikilla kääntäjillä (DICE esimerkiksi) tietyn
koon yli niin onnistuuko muisitn varaus jota voisin taulukon tapaan
käyttää ? entäs moniulotteisen taulukon tapaan ?
int Taulukko[100000] tai int Taulukko[1000][1000]
jos kyllä niin haluaisin mallikoodin.

 

Palle
Perjantaina, 6. elokuuta, 2004 - klo 8.49:   
dynaamisesti varattu taulukko:

int *taulukko;
taulukko = (int*)malloc(100000);

käyttö staattisen taulukon tapaan.

 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 9.05:   
Palle: voiko tehdä moniulotteista ? koska se olisi tärkempää kuin
yksiulotteinen (juuri nyt siis) koska sellaisen muisitpalan osoitus
on hankalaa jos sitä joutuisi käyttämään tyyliin
pohjaosoite+x*kuvanleveys+y selkeämpää olisi kuva[x][y] ja näin isot
kuvat ei mahdu välttämättä ihan kaikkiin taulukoihin.
Ja miten staattista taulukkoa käytetään? vai onko siinä rajoite ettei
sisältö voi muuttua jos on noin eipä tee mitään.:( (tässä hommassa
siis)
PS. tein jo diagnoosin morphedin ja voyagerin yhteistyö
ongelmasta. Josta siis johtuu viestin ulkonäkö. Nytkään en Awebia
jaksnaut käyttää.

 

Palle
Perjantaina, 6. elokuuta, 2004 - klo 9.13:   
tuohon tuli bugi, malloc:lle annetaan tavuina varattava muistin määrä, eli pitäisi olla
malloc( 100000*sizeof(int) );

 

Palle
Perjantaina, 6. elokuuta, 2004 - klo 9.33:   
2-dim taulukon dynaaminen varaus on vähän hankalampi tapaus:

// R - rivit, S-sarakkeet
int **taulu;
taulu=(int**) malloc(S*sizeof(int));
for(int i=0;i<H;i++)
taulu[i] =(int*) malloc(R*sizeof(int));

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 11.45:   
Jos tekee ohjelman, joka on tarkotettu nimenomaan AmigaOS:lle
ja/tai MOS:lle, niin sillon oikestaan kannattaa käyttää malloc:n
sijasta AllocMem(), AllocVec() jne funktioita. Tuollon pystyy
muistinvarausta kontrolloimaan tarkemmin, kuin malloc:n kanssa.
Jos taas on tarkotus tehdä ohjelmsta mahdollisimman helposti
portattava, niin sillon malloc() on ok valinta, malloc() kuitenmin
käyttää kait sisäsesti AllocMem() tjsp kutsua.

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 11.48:   
Niin ja lisäksi esim AmigaOS:n/MOS:n muistipooleja ei voi käyttää
malloc():n kautta, koska se ei ota mitään sellasta parametria missä
kerrottas mitä poolia käytetään.

 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 11.51:   
Palle: tuo ei ollut paha bugi koska osaan hahmottaa kyllä tuon
kohdan.:)
miksuh: niinpä mutta mitä hyötyä AllocMem,AllocVec funktioista on
tuohon nähden ? jos mikä vaan muisti kelpaa.
mitä noi "poolet" on?

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 12.24:   
JPQ: En tiedä osaaanko selittää ton ihan selkeästi,
varsinkin kun olen nukkunut vain hetken täällä Assemblyssä
:) Muistipooli, eli MemoryPool on eräänlainen
muistinhallintamekanismi.

Normaalisti jos sä varaat jonkin pituisen
pätkän muistia, niin käyttis varaa sen jostain löytämästäään
riittävän kokosesta tyhjästä kohdasta muistista. Eli jokainen
muistivaraus voi varata muistia mistäpäin tahansa vapaata muistia,
missä nyt vain sattuu olemaan varattavan mittainen (tai pidempi) vapaa
kohta.

Tosta seuraa helposti se, että muisti pirstoutuu, kun ohjelmat
varailee ja vapauttelee muistia. Muistiin jää pieniä "reikiä".
Muistipooli vähentää muistin pirstoutumista merkittävästi siten, että
se yhdistelee useita pienempiä muistivarauksia isommiksi muistin
pätkiksi.

Jos sä omassa ohjelmassasi varaat muistia käyttäen muistipooleja,
niin ensin poolisysteemi varaa yhden isomman muistipötkön (puddle),
joka sitten näkyy käyttikselle varattuna muistina. Kun
sitten muistia varataan käyttäen muistipoolia, niin sitä muistia ei
varatakaan mistä päin tahansa muistia, vaan tuon isomman muistipätkän
(puddle) sisältä. Kun Puddle tulee täyteen, poolisysteemi
varaa uuden samanlaisen isomman muistipötkön.

Puuddlen sisältä varattuja muistialueita voi sitten varailla ja
vapautella ilman, että se aiheuttaa minkäänlaista pirstoutumista
muistiin. Tottakai puddle voi edelleenkin pirstoutua, mutta kun esim
ohjelman lopussa vapautetaan muistipooli, niin sillon vapautetaan
kkoko se iso pötkö (puddle) kerralla ja mahdollinen puddlen sisäinen
pirstoutumisella ei käytännössä ole mitään merkitystä.

Eli poolien kanssa muisti pirstoutuu AmigaOS:ssa ja
käsittääkseni myös MOS:ssa huomattavasti vähemmän, kuin normaalissa
muistinvarauksessa.

 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 12.38:   
miksuh: Poolit eivät liene ideaan soveltuvia koska useimmiten palat on isohkoja ja etukäteen mitoitettu pala joka noiden palojen varaukseen ei oikein ideana toimi koska tietänet että kuvia paljon eri kokoisia. Nämä komentit ideaani liittyen ja selitys jos meni oikein oli selkeä.

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 12.44:   
JPQ: Jos mikä tahansa muisti kelpaa, niin sillon AllocMem():n
käyttö etu malloc():n verrattuna taitaa ola aika pieni. AllocPooled()
ja AllocVecPooled() etu tulikin selitettyä tossa edellä.

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 12.47:   
JPQ: MuistiPoolista voi toki varata hyvinkin erikokosia palasia,
niiden ei tarvitse olla aina samankokosia. Jos poolista varattu muisti
ei mahdu puddleen, niin sitten poolisysteemi varaa yhden isomman
puddlen.

 

miksuh
Perjantaina, 6. elokuuta, 2004 - klo 13.22:   
JPQ: ja niinkun sanoin, niin malloc() todennäkösesti käytää
jokatapauksessa käyttiksen tarjoamaa AllocMem():a, AllocVec():a
tjsp muistinvaraukseen. Eli tuntuu vähän hassulta lisätä ylimääränen
rajapintakerros muistinvarauskutsuun, jos sitä ei esim koodin
portattavuuden takia tarvitse. Tuskin se ohjelman suoritusnopeudessa
näkyy, mutta silti..

 

itix
Perjantaina, 6. elokuuta, 2004 - klo 13.40:   
malloc() on siinä mielessä parempi että varattu muisti vapautuu ohjelman päätyttyä.

 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 14.16:   
miksuh: voi mutta jos palanen loppuu kesken se oli se ongelma. koska en halua tietyn tyylin rajoja ohjelmaani että vaikkapa 4096x3072 kuvia ei voi olla auki kuin yksi jos poolista loppuisi tila.
itix: hyvä tietää tuo plussaa mun kaltaisille koodareille tosin sanoit hämäästi jos aloittelijat lukee tätä eli kyllähän allocmemilläkin varatun voi vapauttaa lopussa. (tosin saa olla aika alussa ettei tiedä tuota) Ja oliko joku käyttis kutsukin joka vapautuksesta huolehti itse.

 

itix
Perjantaina, 6. elokuuta, 2004 - klo 14.38:   
JPQ: Muistipooli kasvaa tarpeen mukaan. Voit varata miten isoja paloja tahansa.

MorphOS:ssa on myös AllocTaskPooled() ja AllocVecTaskPooled() joita voi käyttää. Ne varaavat muistin ohjelman omasta poolista ja muisti vapautuu automaattisesti ohjelman päätyttyä.

 

JPQ
Perjantaina, 6. elokuuta, 2004 - klo 17.58:   
itix: no sitten voi kuulostaa järkevältä tässäkin hommassa mutta
oletan että ekoja kertaa ideaa testaan "perinteisemmin".

 

allu
Perjantaina, 6. elokuuta, 2004 - klo 17.58:   
JPQ: "on hankalaa jos sitä joutuisi käyttämään tyyliin pohjaosoite+x*kuvanleveys+y selkeämpää olisi kuva[x][y]", voithan sä tehdä siihen makron.

Tyyliin:

#define PIXEL(X, Y) bmap[((Y) * width) + (X)]

Ja varaukset on näin:

int width, height;
int *bmap; // jos välttämättä haluaa
// käyttää int-taulukkoa

width = 1024;
height = 768;

bmap = malloc(width * height * sizeof(int));
// tai bmap = calloc(width * height, sizeof(int));

Lisää viestisi tähän
Viestisi:
Käyttäjätunnus: Postitus informaatiota:
Tämä on yksityinen keskustelupalsta. Vain rekisteröidyt käyttäjät ja moderaattorit voivat postittaa tänne.
Salasana:
valinnat: Aktivoi URL:t automaattisesti tässä viestissä
Toimenpide: