Indice del forum Olimpo Informatico
I Forum di Zeus News
Leggi la newsletter gratuita - Attiva il Menu compatto
 
 FAQFAQ   CercaCerca   Lista utentiLista utenti   GruppiGruppi   RegistratiRegistrati 
 ProfiloProfilo   Messaggi privatiMessaggi privati   Log inLog in 

    Newsletter RSS Facebook Twitter Contatti Ricerca
[c] free() ...
Nuovo argomento   Rispondi    Indice del forum -> Programmazione
Precedente :: Successivo  
Autore Messaggio
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 25 Set 2008 09:44    Oggetto: [c] free() ... Rispondi citando

Buondì, intanto...
Ho un dubbio...
Se ho un vettore di struct, allocato con calloc, e volessi eliminare un elemento va bene questo algoritmo?


(elem è puntatore alla struct)
remove(...)
{
elem = cerca_elemento da eliminare();
se lo trovi
prev_element = elem -1;

sposta con memcpy()tutti gli elementi che seguivano elem di 1 posizione indietro(incremento: prev = elem; elem=elem+1; )

free(elem) //che qui punta all'ultimo elemento dell'array, ormai doppione del penultimo
}
Insomma, mi chiedevo se, trattandosi di un vettore, è possibile deallocare solo l'ultima cella oppure se la free deve coinvolgere tutta l'area allocata da calloc (ovvero tutto il vettore)
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 25 Set 2008 12:52    Oggetto: Re: [c] free() ... Rispondi citando

approccio curioso un vettore di struct...

a parte il parere personale, se la lunghezza del vettore cambia dinamicamente già vuol dire che probabilmente il vettore non era una buona soluzione, forse meglio optare per una lista.

Se invece non puoi fare altrimenti (facciamo finta... per motivi didattici ad esempio) allora penso che la cosa migliore sia aggiungere un flag booleano 'cancellato' alla tua struct e quando farai una cancellazione di un elemento NON ti metterai a ricopiare tutti i successivi e poi a ridimensionare l'array, sono operazioni molto dispendiose in termini di performance, ma semplicemente cambierai lo stato del flag.

Ciao
Top
Profilo Invia messaggio privato HomePage
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 25 Set 2008 13:49    Oggetto: Rispondi citando

in realtà la dimensione non dovrebbe cambiare... ma sai, volevo dare la possibilità di farlo (per casi estremi) a chi volesse modificare il mio sorgente. (di certo non mi metterò ad implementarli io...)
Non avevo mai usato un vettore di struct, ma sempre vett di puntatori a struct,e devo dire... che facevo bene.

Il flag cel'ho già, può rappresentare ben 3 stati: attivo, disattivo per tot tempo e disattivo per sempre(che comunque può essere modificato, serve a me per non considerarlo in certe occasioni)
lunica cosa che mi rimane dubbia è:
Question
le struct dentro il vettore hanno un campo char* che viene allocato a suo tempo.
Nel liberare il vettore cercavo di fare prima una free su tutti questi char*, poi sul vettore stesso. Mi da seg.fault nella free().
Se faccio solo la free() sul vettore mica libero anche le stringhe corrispondenti ad ogni struct !!!

Che posso fare?
Top
Profilo Invia messaggio privato
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 25 Set 2008 14:16    Oggetto: Rispondi citando

[RISOLTO]
ho sostituito il while per rimuovere le stringhe con un for... e la magia è fatta.
Grazie! Very Happy
Top
Profilo Invia messaggio privato
chemicalbit
Dio maturo
Dio maturo


Registrato: 01/04/05 18:59
Messaggi: 18597
Residenza: Milano

MessaggioInviato: 25 Set 2008 20:58    Oggetto: Re: [c] free() ... Rispondi citando

SverX ha scritto:
se la lunghezza del vettore cambia dinamicamente già vuol dire che probabilmente il vettore non era una buona soluzione, forse meglio optare per una lista.
Cioé, come?
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 26 Set 2008 11:54    Oggetto: Re: [c] free() ... Rispondi citando

chemicalbit ha scritto:
SverX ha scritto:
se la lunghezza del vettore cambia dinamicamente già vuol dire che probabilmente il vettore non era una buona soluzione, forse meglio optare per una lista.
Cioé, come?


Una lista è un elenco di elementi -ognuno allocato dinamicamente- che contengono un campo 'puntatore al prossimo elemento' (almeno nel caso più semplice, le liste semplici, appunto).

Basta avere definito staticamente il puntatore al primo elemento e poi si tratta di 'saltare' da ognuno al successivo finchè non si trova quello desiderato. Per rimuoverlo basta fare sì che l'elemento precedente a quello da rimuovere punti al successivo (sempre di quello da rimuovere) e poi si può deallocare tranquillamente l'elemento da cancellare.

(se ti interessa l'argomento, è spiegato meglio ad esempio qui ... )

Ciao
Top
Profilo Invia messaggio privato HomePage
chemicalbit
Dio maturo
Dio maturo


Registrato: 01/04/05 18:59
Messaggi: 18597
Residenza: Milano

MessaggioInviato: 26 Set 2008 12:17    Oggetto: Rispondi citando

Ah sì, ho capito, una lista in cui ogni elemento punta al successivo.

(Una sua "evoluzione" è consentire delel diramazioni, creando degli "alberi", giusto?)
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 26 Set 2008 16:47    Oggetto: Rispondi citando

chemicalbit ha scritto:
Ah sì, ho capito, una lista in cui ogni elemento punta al successivo.
(Una sua "evoluzione" è consentire delel diramazioni, creando degli "alberi", giusto?)


Un albero è un concetto topografico, è un grafo connesso e privo di cicli, e si può creare utilizzando delle liste multiple (ovvero delle liste che puntano a più di un altro nodo... se poi il numero di nodi a cui ognuno può puntare fosse variabile allora converrà che ogni nodo abbia una propria lista di collegamenti ai nodi...)

(dopo essermi scervellato a pensare come spiegarlo ho trovato una spiegazione migliore qui... Smile )
Top
Profilo Invia messaggio privato HomePage
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 09 Mar 2010 12:45    Oggetto: Ancora su free()... Rispondi citando

Salve... a me questa free non sta proprio simpatica...

Mi stavo chiedendo, quando è effettivamente necessario, dopo una chiamata a "free(ptr)" effettuare anche una "ptr = NULL" .

Come noto la "free" rende nuovamente disponibile la memora puntata da "ptr" ma esso continua a puntare a quell'area, giusto?

E allora... quando non si puo' far a meno di fare
Codice:

{
...
free(ptr);
ptr = NULL;
...
}


???

Grazie.
Top
Profilo Invia messaggio privato
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 09 Mar 2010 12:52    Oggetto: Rispondi citando

La free libera la memoria quindi fisicamente questa ridiventa disponibile.
La parte "libera la memoria" va intesa come "libera la cella di memoria puntata dal puntatore".
Ptr fisicamente occupa 32bit e questi non vengono liberati mai (neppure con il NULL) perchè free non libera la memoria occupata dal puntatore ma quella puntata dallo stesso.
Forse un po' crocchio come giro però devi distinguere la memoria puntata da quella occupata dal puntatore stesso.
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 09 Mar 2010 16:29    Oggetto: Re: Ancora su free()... Rispondi citando

saetta ha scritto:
Come noto la "free" rende nuovamente disponibile la memora puntata da "ptr" ma esso continua a puntare a quell'area, giusto?


Sì, continua a valere quello che valeva prima e quindi a puntare ad un'area di memoria non riservata nello heap. Di conseguenza è da non usare più, a meno di non avere una nuova malloc()
Top
Profilo Invia messaggio privato HomePage
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 09 Mar 2010 23:58    Oggetto: Rispondi citando

Ok, questo mi è chiaro e ne deduco che la necessità di mettere a NULL un ptr che ha appena "subìto" una free() sopraggiunga in caso di controlli su di esso, dopo una free(). O no ? Embarassed
Codice:

...
if(cond)
{
free(ptr);
ptr = NULL;
}

if (ptr == NULL)
fai_qualcosa();
Top
Profilo Invia messaggio privato
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 10 Mar 2010 00:32    Oggetto: Rispondi citando

Quello che hai scritto ci sta!
L'usare NULL serve ad avere un valore che sia in qualche modo distinguibile dai possibili contenuti che può assumere la variabile.
NULL vuol dire "niente" quindi se il tuo puntatore è NULL vuol dire che non sta puntando a nulla.
In pratica il tuo codice potrebbe essere riscritto con una sentinella tipo:
Codice:

...
setinella=1;
if(cond)
{
free(ptr);
sentinella=0;
}

if (sentinella==0)
{
  fai_qualcosa(); // tra cui riassegnare ptr anche se non lo hai messo a NULL
}


In pratica NULL è un valore neutro che può essere assegnato ai puntatori per dire che in quel momento è disponibile oppure per indicare qualunque altra cosa.

Codice:

ptr=NULL;
ptr=&a;

in entrambi i casi la variabile ptr è allocata nello stack e occupa 32bit; la memoria che viene liberata con free e allocata con malloc/calloc è quella dello heap.
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 10 Mar 2010 17:12    Oggetto: Rispondi citando

saetta ha scritto:
Ok, questo mi è chiaro e ne deduco che la necessità di mettere a NULL un ptr che ha appena "subìto" una free() sopraggiunga in caso di controlli su di esso, dopo una free(). O no ?


Niente ti vieta di mettere a NULL un puntatore e poi di fare dei test sul puntatore per capire se sta puntando a qualcosa o no, ma non c'è una reale necessità. Ad esempio in una lista se rimuovi un elemento non hai bisogno di mettere a NULL il membro puntatore all'elemento successivo, tanto stai buttando via tutto, che ti frega? Idem per una variabile locale:

Codice:
void function finta (item* myItem) {
  item* ptr = myItem->next;
  rimuovi(ptr);
}


a che servirebbe mettere ptr a NULL?
Top
Profilo Invia messaggio privato HomePage
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 10 Mar 2010 18:52    Oggetto: Rispondi citando

Grazie ragazzi, ora è un po' più chiaro... e spero di non dover litigare nuovamente con free() altrimenti questo topic diventa kilometrico... Anxious
Top
Profilo Invia messaggio privato
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 10 Mar 2010 19:49    Oggetto: Rispondi citando

saetta ha scritto:
Grazie ragazzi, ora è un po' più chiaro... e spero di non dover litigare nuovamente con free() altrimenti questo topic diventa kilometrico... Anxious

Io ti auguro di non aver più problemi con la funzione free() però anche se il 3d diventa kilometrico non c'è nessun problema, anzi, vuol dire che c'è ancora chi si diverte con il C!!!!

bauuuu
Top
Profilo Invia messaggio privato
saetta
Eroe in grazia degli dei
Eroe in grazia degli dei


Registrato: 25/02/08 11:52
Messaggi: 129

MessaggioInviato: 11 Mar 2010 00:14    Oggetto: Rispondi citando

E invece...rieccomi...

se ho una struct che come membri oltre che tipi di dato "classici" (int, char, array ecc.) anche PUNTATORI A FUNZIONI...

all'atto della cancellazione della struct devo fare per ogni "membro-ptr a funzione" questo(?):

Codice:

free((mystruct)->ptr_a_fne1);
free((mystruct)->ptr_a_fne2);
...
free((mystruct)->ptr_a_fneN);


oppure semplicemente, essendo puntatori a funzione mi dealloco la struct e via?
Codice:

free(mystruct) ;


Nel primo caso credo di deallocare anche la memoria riservata alla funzione (membro di struct) mentre nel secondo elimino semplicemente il riferimento ad essa...o no?

LOL non troverò mai pace con il C...soprattutto a quest'ora...buonanotte!
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 11 Mar 2010 16:59    Oggetto: Rispondi citando

ma no, non devi deallocare nessun puntatore a funzione, mica hai allocato dello spazio nello heap!
In pratica non devi mai fare free() di niente che non hai allocato con una malloc(). Per dire, se hai una struct definita come variabile globale e poi punti a quella con un puntatore, poi mica usi la free().
Invece se hai un puntatore che usi per puntare ad una struttura che hai malloc()-ato nello heap allora sì, devi deallocare prima di usare il puntatore per altro/perderti il puntatore, altrimenti avrai un c.d. memory leak
Top
Profilo Invia messaggio privato HomePage
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 12:16
Messaggi: 11809
Residenza: Tokelau

MessaggioInviato: 11 Mar 2010 17:02    Oggetto: Rispondi citando

freemind ha scritto:
[...] anzi, vuol dire che c'è ancora chi si diverte con il C!!!


problemi? TapTap TapTap TapTap
Top
Profilo Invia messaggio privato HomePage
freemind
Supervisor sezione Programmazione
Supervisor sezione Programmazione


Registrato: 04/04/07 21:28
Messaggi: 4643
Residenza: Internet

MessaggioInviato: 11 Mar 2010 17:17    Oggetto: Rispondi

SverX ha scritto:
freemind ha scritto:
[...] anzi, vuol dire che c'è ancora chi si diverte con il C!!!


problemi? TapTap TapTap TapTap

Aò, guarda che io sono quello di "Sesso Alcool e C++" mica bau bau micio micio!
Il C è una gran cosa e il mio commento era sincero!
Non trattarmi male SverX, sono sensibile!

Fine ot
Top
Profilo Invia messaggio privato
Mostra prima i messaggi di:   
Nuovo argomento   Rispondi    Indice del forum -> Programmazione Tutti i fusi orari sono GMT + 2 ore
Vai a 1, 2  Successivo
Pagina 1 di 2

 
Vai a:  
Non puoi inserire nuovi argomenti
Non puoi rispondere a nessun argomento
Non puoi modificare i tuoi messaggi
Non puoi cancellare i tuoi messaggi
Non puoi votare nei sondaggi