[C] Allocazione dinamica

di Paolovox il
9 risposte
Se ho ad esempio un puntatore ad un puntatore di struct Persona:

Persona **p = malloc(sizeof(Persona));
Il primo puntatore conterrà l'indirizzo del puntatore che punterà alle struct Persona. Qui la mia prima domanda è: non basterebbe allocare spazio per un intero e non per la sizeof(Persona) così:
Persona **p = malloc(sizeof(int))
.

Poi continuando:

*p = (Persona *)malloc(sizeof(Persona)*42);
La mia seconda domanda è: adesso per liberare tutte le risorse utilizzate mi basta fare
free(p)
? Oppure devo eseguire una free per ogni elemento puntato da *p e poi di p??

Grazie e buona giornata

9 Risposte

  • ORRORE (che e' peggio di errore):
    
    Persona **p = malloc(sizeof(Persona));
    
    SBAGLIATO, doveva essere:
    
    Persona *p = malloc(sizeof(Persona));
    
    nota UN SOLO asterisco, NON DUE

    che e' DIVERSO da questo:
    
    Persona **p = malloc(sizeof(Persona*));
    


    1) sizeof(Persona) | sizeof(int) probabilmente si, ma ci sono tutta una serie di considerazioni da fare

    - perche' lo vorresti fare? In altri termini, perche' cercare rogne?
    - tu NON SAI se il compilatore aggiunge delle informazioni di servizio alla struct che vengono poi allocate, oppure, molto piu' probabilmente, decide degli allineameti ad indirizzi multipli di 4/8 byte

    2) malloc/free allocano e liberano BLOCCHI di memoria, non sanno che cosa c'e' dentro, E VANNO SEMPRE IN COPPIA.

    - non puoi DEALLOCARE SOLO UNA PARTE di un blocco allocato con la malloc
  • Hai dato del codice (sbagliato) ma non hai fatto una domanda chiara.

    Tu cosa devi fare?
  • Non devo fare nulla e migliorabile ha risposto alle mie domande in modo esaustivo ed ora lo terrò bene a mente

    Grazie
  • Mah ... quando migliorabile dice
    Persona **p = malloc(sizeof(Persona));

    SBAGLIATO, doveva essere:

    Codice: Seleziona tutto
    Persona *p = malloc(sizeof(Persona));
    non è detto che sia così ... ovvero

    Persona **p = malloc(sizeof(Persona));

    è sbagliato, ma probabilmente tu volevi scrivere questo

    Persona **p = (Persona **)malloc(42 * sizeof(Persona *));

    e quindi allocare ogni elemento del vettore con

    for(i=0; i<42; i++)
    p = (Persona *)malloc(sizeof(Persona));

    e quindi le free andranno scritte in senso inverso.

    Ma non lo sapremo se non indichi effettivamente il problema.
  • Giusto quindi così facendo:
    
    Persona **p = (Persona **)malloc(sizeof(Persona *)*2);
    
    int i;
    for(i=0;i<2;i++)
    {
    	*(p+i) = (Persona *)malloc(sizeof(Persona)*4);
    }
    
    ottengo un puntatore ad un array di puntatori, contenenti struct Persona, di dimensione 4.
    Adesso effettuo le free prima per i puntatori agli array e poi per il puntatore all'array di puntatori;
    
    int i;
    for(i=0;i<2;i++)
    {
    	free(*(p+i));
    }
    free(p);
    
    Il mio scopo era avere un puntatore ad un array di puntatori.
    Grazie.
  • Il mio scopo era avere un puntatore ad un array di puntatori..
    Ecco ... per questo ti dicevo che prima si indica il problema, si spiega cosa si vuole ottenere e poi si parla di codice.
    *(p+i) = (Persona *)malloc(sizeof(Persona)*4);

    struct Persona, di dimensione 4.
    No, questo non ha senso. Devi allocare un solo elemento Persona con

    *(p+i) = (Persona *)malloc(sizeof(Persona));

    Che c'entra il 4?

    Con quello che hai scritto hai un vettore di 2 puntatori a struttura Persona (un vettore di 2 elementi).
    Se vuoi ottenere altro, spiegati meglio ...
  • Ecco spero di essere più chiaro con un disegnino.



    Con:
    Person **p = (Person **)malloc(sizeof(Person *)*2)
    avrò il primo puntatore a ad un array di due puntatori a Person.

    Con:
    
    int i;
    for(i=0;i<2;i++){
    	*(p+i)=(Person *)malloc(sizeof(Person)*4);
    }
    
    avrò che i "secondi puntatori" puntano a due array di Person di lunghezza 4.

    Cosa sbaglio??
  • Questa è una matrice dinamica (era la domanda da fare nel primo post), ma così non puoi gestire facilmente i singoli elementi. Ti serve un tripo puntatore
    
    	int i, k;
    
    	Persona ***matrice=(Persona ***)malloc(2 * sizeof(Persona **));
       
        for (i=0; i<2; i++)
        {
    		matrice[i]=(Persona **)malloc(4 * sizeof(Persona *));
    
            for (k=0; k<4; k++)
                matrice[i][k]=(Persona *)malloc(sizeof(Persona));    
        }
    
  • Ook grazie mille penso di aver capito.
    Il mio problema è il seguente?!?
    
    Persona **p = (Person **)malloc(2*sizeof(Persona *));
    
    int i;
    for(i=0;i<2;i++){
       *(p+i)=(Persona *)malloc(4*sizeof(Persona));
       
       int j;
       for(j=0;j<4;j++)
       {
       	(*(*p+i)+j) = //questo non sarà a puntatore ad una struct Persona e quindi non posso allocare lo spazio per utilizzarla
       }
       
    }
    
Devi accedere o registrarti per scrivere nel forum
9 risposte