On 20 Oct 00, at 7:03, wrote:
> Memoriafogalalsok teren a szakirodalom az ajanlotta,
> (a memallloc az egy lassu dolog) hogy egy nagyobb
> tombot foglaljunk le a rendszertol (n darab m elemut)
> es abba oldjuk meg kisded foglalasainkat (+atobbit).
Ilyesmi, csak nem 1 darab nagyot, hanem annyi nagyot,
amennyire szukseg van. (Felteszem ugyanis, hogy nem tudsz
elore felso korlatot adni a memoriadarabok szamara, mert akkor
tombot hasznalnal.)
Rogtonzok egy ilyet:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
struct egyelem { // egy elemi memoriadarab
char LM[20]; // itt lehet barmi mas is...
};
#define ELEMEK 1000 // egyszerre ennyit foglalunk le egy nagyban
struct memLM; // ez lesz a "nagy" objektum
#ifdef _DEBUG
// esetleges feluliras elleni ellenorzes
char ALAIRAS[] = "alairas";
#endif
struct egyLM {
egyelem LM; // a memoria maga! ELOL KELL LEGYEN!!!!
// a sebesseg miatt elemenkent is adminisztralunk:
#ifdef _DEBUG
char alairas[sizeof(ALAIRAS)];
#endif
memLM *holLM; // melyikben van benne?
int indLM; // melyik index is ez?
};
struct memLM {
memLM *kov; // lancoljuk a nagyokat
int elsoszabad; // legelso szabad index
int szabadok[ELEMEK]; // szabadok indexlanca
egyLM foglaltak[ELEMEK]; // "A" tomb
};
memLM *elsonagy = NULL; // ez lesz a nagyok lanca
egyelem *LMalloc()
{
memLM *akt = elsonagy;
while (akt && -1 == akt->elsoszabad)
akt = akt->kov; // ebben mar nincs szabad hely
if (!akt) { // egyaltalan nincs szabad
// allokalunk uj nagyot
akt = (memLM *)malloc(sizeof(memLM));
if (!akt) return NULL; // ciki...
akt->kov = elsonagy;
elsonagy = akt;
// inicialjuk memLM-et:
akt->elsoszabad = 0; // lanc eleje
for (int i=0; i<ELEMEK-1; i++)
akt->szabadok[i] = i+1;
akt->szabadok[ELEMEK-1] = -1; // lanc vege
}
// az akt tomb elsoszabad eleme allokalhato:
int ind = akt->elsoszabad;
akt->elsoszabad = akt->szabadok[ind];
egyLM *aktLM = &(akt->foglaltak[ind]);
// egyedi adminisztralas a free-hez:
#ifdef _DEBUG
strcpy(aktLM->alairas, ALAIRAS);
#endif
aktLM->holLM = akt;
aktLM->indLM = ind;
return &(aktLM->LM);
}
void LMfree(egyelem *cim)
{
egyLM *aktLM = (egyLM *)cim; // ugyanaz a cim!!!!
#ifdef _DEBUG
if (strcmp(aktLM->alairas, ALAIRAS)) {
// Ciki... felulirodott!!!
fprintf(stderr, "Felulirodott a mem!\n");
exit(111); // vagy normalisabb hibajelzes...
}
#endif
memLM *akt = aktLM->holLM;
int ind = aktLM->indLM;
// attesszuk a szabadok koze:
akt->szabadok[ind] = akt->elsoszabad;
akt->elsoszabad = ind;
}
> -----------------------------------------------
Nehany megjegyzes: Szoktak olyat csinalni, hogy a szabad
elemek adminisztralasat magaban a szabadda valt elemben teszik
meg, nem pedig egy kulon helyen (mint fentebb a szabadok tomb).
Olyan modon kevesebb memoriat foglalna az egesz, viszont ha
egy felszabaditott memoriaba kesobb (egy bug folytan) beleirna
valaki, akkor az egesz memoriamenedzseles romlana el, ami
aztan nehezen debugolhato hibakat okozhat. Hasonlo problemat
okozhat -- bar ritkabban -- az is, amit itt is alkalmaztam, hogy a
visszaadott memoriadarab mogott van valami adminisztrativ dolog.
Ha az folulirodna egy bugtol, megint csak nehezen debug-olhato
helyzetet okozhatna. Erre itt csak egy debug-os forditaskor
belekerulo alairassal vedekezem (mar amennyire -- egy check sum
szeru dolog jobb lenne). Az indLM-re valojaban nem lenne
szukseg, hisz azt a cimbol es holLM-bol mar ki lehetne szamolni,
de igy tisztabb a dolog.
Nem probaltam ki rendesen, csak annyira, hogy ne legyen benne
szintaktikus hiba :)
István
|