Newsgroup: it.comp.lang.c
Titolo: Deallocare memoria

Ciao,
mettiamo che state caricando un file, di testo o binario non importa.
Avrete una procedura di tipo:
LoadFile(f)
carica_info_1(file);
carica_info_2(file);
.....
Ogni funzione carica_info_*() dovrà accedere al file e probabilmente
allocare la memoria
ecc...
Se però il file è corrotto/invalido, uno deve interrompere il
caricamento e restituire un
messaggio di errore. Però, tutta la memoria allocata dalle varie
funzioni carica_info
va deallocata...un incubo.
Voi normalmente che fate? Non esiste un modo per fare una cosa simile?
beginmemorymarker()
if (LoadFile(f) == BAD)
   endmemorymarker_and_delete()
else
   endmemorymarker_ok()
   return OK
cioè, della serie: setto un marker, alloco a volontà:se tutto ok,
tolgo il marker, altrimenti
lo tolgo lo stesso, ma con una funzione che libera (automaticamente)
tutta la memoria
occupata.
So che in C non esiste niente di simile (e nemmeno in C++, o forse
sbaglio?).Mi
rivolgo a voi perchè sarete dei programmatori e forse avete già
risolto questo
problema...
Ciao

occupata.
Puoi adottare un tuo memory manager che tenga traccia delle
allocazioni.  Quello di seguito l'ho scritto al volo e testato
pressoché per nulla, è artigianale ma ti dà un'idea:
#include <stdio.h>
#include <stdlib.h>
/* memory block */
typedef void *memblk_t;
/* memory manager */
typedef struct {
        int count;
        memblk_t *memblk;
} memmgr_t, *pmemmgr_t;
/* creazione del memory manager */
pmemmgr_t memmgr_create(int count) {
     pmemmgr_t i=malloc(sizeof *i);
     if (i) {
        i->count=count;
        i->memblk=calloc(count, sizeof *(i->memblk));
     }
     return i;
}
/* allocazione di un puntatore */
void *memmgr_malloc(pmemmgr_t self, size_t dim) {
     void *ret=0;
     if (self) {
        int i=0;
        for (i=0; i<self->count; i++)
            if (self->memblk[i]==0) {
               ret=self->memblk[i]=malloc(dim);
               break;
            }
     }
     return ret;
}
/* deallocazione di un puntatore */
int memmgr_free(pmemmgr_t self, void *p) {
     int i, ret=0;
     if (self) {
        for (i=0; i<self->count; i++) {
            if (self->memblk[i]==p) {
               free(self->memblk[i]);
               self->memblk[i]=0;
               ret=1;
               break;
            }
        }
     }
     return ret;
}
/* liberazione di tutta la memoria allocata */
void memmgr_free_all(pmemmgr_t self) {
     if (self) {
        int i;                
        for (i=0; i<self->count; i++) {
            if (self->memblk[i]) {
               free(self->memblk[i]);
               self->memblk[i]=0;
            }
        }
     }
}
/* distruzione del memory manager */
void memmgr_destroy(pmemmgr_t self) {
     if (self) {
        memmgr_free_all(self);
        free(self);
     }
}
/* output del contenuto della memoria */
void memmgr_dump(pmemmgr_t self) {
     if (self) {
        int i;
        for (i=0; i<self->count; i++) {
            printf("block n. %d", i); 
            if (self->memblk[i])
               printf("- allocated bytes: %d at address %p\n",
                      i, self->memblk[i]);
            else
               printf("- not allocated\n");   
        }       
     }
     else printf("...nothing to print!\n");
}
int main()
{
    pmemmgr_t mm=0;
    void *p[10];
 
    mm=memmgr_create(5);
    printf("situazione iniziale: \n");
    memmgr_dump(mm);
 
    p[0]=memmgr_malloc(mm, 100);
    printf("--\n");
    memmgr_dump(mm);
    p[1]=memmgr_malloc(mm, 200);
    printf("--\n");    
    memmgr_dump(mm);
 
    memmgr_free(mm, p[0]);
    printf("--\n");    
    memmgr_dump(mm);
 
    p[3]=memmgr_malloc(mm, 50);
    printf("--\n");    
    memmgr_dump(mm);
 
    memmgr_free_all(mm);
    printf("--\n");    
    memmgr_dump(mm);
 
    memmgr_destroy(mm);
 
    return 0;
}

 problema...
Mi viene in mente un 'garbage collector'. C'e' in tutti linguaggi di 
alto ed altissimo livello, quelli per cui non ti devi preoccupare di 
allocare e disallocare memoria dinamica (eg. java, c#, perl, php, 
python,... lunga lista).
Nel C++, se ben ricordo, un garbage collector era gia' presente nelle 
librerie del primo Borland C++ (mai provata).
Qui pero' trovi una versione anche per il C (se vuoi provala):
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
Un'altra possibile soluzione (piu' snella) ho visto che te l'hanno gia' 
postata.
Ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

librerie del primo Borland C++ (mai provata).
Huh ? mai sentito... 

Andrea Laforgia ha scritto:

...puo' anche essere che me lo sia sognato :-)
Magari se qualcuno si ricorda...
