|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
[C++] double free alla prima free()
Ho una struttura
Codice:
struct Struttura{ tipo **matrice; }; Codice:
Struttura * var = (Struttura *) malloc(sizeof(Struttura)); Struttura->matrice = (tipo **) malloc(dimensione * sizeof (tipo *)); for (int i = 0; i < altra_dimensione; i++) { Struttura->matrice[i] = (tipo *) malloc(altra_dimensione * sizeof (tipo)); } più avanti ancora decido di deallocare tutto: Codice:
for(int i=0;i<dimensione;i++){ free(Struttura->matrice[i]); } ... double free or corruption (out): 0x08ccb060 Ho guardato ovunque, non ho trovato una soluzione che funzioni. C'è qualche errore in ciò che faccio? Se non chiamo la free il programma funziona correttamente, e anzi vi dirò di più... se al posto del ciclo per deallocare la matrice ci metto un doppio ciclo per stampare i valori della matrice, me li stampa senza problemi. Questo significa che la memoria non è stata già deallocata e non è nemmeno corrotta. (Nota: Se non dealloco la matrice ma dealloco la Struttura, funziona, ma suppongo che resti della memoria spazzatura, per questo insisto per deallocare la matrice. Ho notato che se ciclo l'esecuzione del programma infinite volte, la memoria allocata continua a crescere, quindi suppongo che sia a causa di questa mancata deallocazione) (per semplificare il codice non l'ho scritto, ma in realtà la struct Struttura è puntata da un puntatore all'interno di un'altra struttura, ma non credo che la cosa sia rilevante) Ultima modifica di Barbalbero : 03-04-2011 alle 23:42. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Se stai effettivamente usando C++ non usare assolutamente malloc e free.
Per quanto riguarda il tuo errore mi sembra che il problema possa essere l'indice su cui iteri: malloc: for (int i = 0; i < altra_dimensione; i++) free: for(int i=0;i<dimensione;i++) Oppure potrebbe essere qualcos'altro che non hai postato. |
![]() |
![]() |
![]() |
#3 |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
il bound del ciclo forse l'ho copiato sbagliato, ma se il problema fosse quello il problema salterebbe fuori solo ad una certa iterazione, non alla prima, come accade adesso.
Le altre cose che faccio nel programma non credo siano rilevanti, poiche si tratta solo di operazioni sui dati, nessun'altra free. Ora non posso, ma più tardi proverò a deallocare immediatamente dopo l'allocazione, per esserne sicuro. Perchè non devo usare malloc? advanced linux programming consiglia di usare malloc |
![]() |
![]() |
![]() |
#4 | |
Member
Iscritto dal: Apr 2008
Messaggi: 55
|
Quote:
|
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
@Barbalbero: potresti usare Valgrind per scoprire il problema.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#6 | ||
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
ok ho provato un nuovo codice:
Codice:
struttura->tab->nrows = dim; struttura->tab->ncols = 2 * dim + 3; struttura->tab->matrix = (mpf_t **) malloc(struttura->tab->nrows * sizeof (mpf_t *)); for (int i = 0; i < struttura->tab->ncols; i++) { struttura->tab->matrix[i] = (mpf_t *) malloc(struttura->tab->ncols * sizeof (mpf_t)); } for (int i = 0; i < struttura->tab->ncols; i++) { free(struttura->tab->matrix[i]); } In tab c'è un array bidimensionale matrix con le relative dimensioni. in pratica ho provato a deallocare subito dopo aver allocato lo spazio, per vedere se era colpa di qualche operazione intermedia. Il problema persiste. Quote:
Quote:
Secondo me il problema comunque è molto banale, guardate il codice nuovo. Sono 4 righe di codice, evidentemente faccio qualcosa di non permesso, non lo so, per esempio mettere un array in una struttura dentro un'altra struttura, non ne ho idea |
||
![]() |
![]() |
![]() |
#7 |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
ok forse ho un'illuminazione. Forse il problema sta nella libreria GMP. Probabilmente devo fare qualcosa prima di deallocare questo tipo di dato.
Ora cerco sulla guida poi vi faccio sapere |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Dove deallochi struttura->matrice ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
![]() |
![]() |
![]() |
#9 |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
|
![]() |
![]() |
![]() |
#10 | |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
Quote:
|
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
malloc è la funzione di allocazione del C. Il primo problema che si presenta utilizzando malloc invece di new è che non viene richiamato il costruttore della classe, pertanto cadono un bel po' di postulati del C++. Per quanto riguarda advanced linux programming molto probabilmente parla delle librerie di sistema che sono in C. Anche ieri ho trovato su un forum che consigliavano di utilizzare valgrind, ma essendo un debugger non credo che potrà aiutarmi. Però ora lo installo e se non è troppo complicato vedo se può essermi d'aiuto. Secondo me il problema comunque è molto banale, guardate il codice nuovo. Sono 4 righe di codice, evidentemente faccio qualcosa di non permesso, non lo so, per esempio mettere un array in una struttura dentro un'altra struttura, non ne ho idea[/quote] |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Sfortunatamente C++ duplica gran parte delle strutture di C, ma spesso lo fa saltando dei pezzi
![]() Ci sono molti casi in cui quello che si vuole fare è proprio allocare della memoria non inizializzata per un'uso futuro, e in quel caso new oltre a essere lento è anche abbastanza pericoloso; ad esempio se fai new float*[n] ti dovrai ricordare di non chiamare delete, ma delete[]. Che per quanto mi riguarda è una schifezza, ed è anche inutilmente non trasparente rispetto a malloc/free, che se si sa cosa si sta facendo sono molto più chiari e sicuri (allochi n byte, se non riesce da NULL. Punto.). Per non parlare di tutti quei casi in cui si manovrano i singoli byte, e allora malloc è perfetto. E tra l'altro nemmeno new[] e delete[] chiamano i costruttori/distruttori ![]() E vogliamo parlare dell'overload di new, o del fatto che new non ha un comportamento definito in caso di errore? Io più imparo C++ più mi rendo conto di usare un "C con le classi", tanta, troppa roba "avanzata" in C++ è semplicemente stata realizzata male e complica soltanto la vita, partendo dalla STL per finire ai templates. Quindi pls prima di dire boiate come "lol c'hai C++ usa new" pensateci ![]() Ultima modifica di Tommo : 04-04-2011 alle 17:03. |
![]() |
![]() |
![]() |
#13 | |
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
Quote:
Tornando al problema iniziale. L'errore era dovuto al fatto che gli elementi della matrice sono di un tipo definito nella libreria GMP. Se dopo aver chiamato la mpf_clear su ogni elemento della matrice, tento di applicare la free alla matrice mi fa il solito errore double free. Quindi penso che mpf_clear applichi la free anche alla matrice stessa, che ne dite? |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
Eh? Ovvio che li chiamano. È proprio per quello che le versioni [] sono separate.
Ultima modifica di ||ElChE||88 : 04-04-2011 alle 18:43. |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12816
|
Quote:
Ultima modifica di WarDuck : 04-04-2011 alle 18:39. |
|
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Quote:
Prova e verrai piacevolmente sorpreso ![]() |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
Quote:
![]() Codice:
#include <iostream> class Test { public: Test() { std::cout << "ctor" << std::endl; }; ~Test() { std::cout << "dtor" << std::endl; }; }; int main(int argc, char **argv) { int count; std::cin >> count; Test *test = new Test[count]; delete[] test; return EXIT_SUCCESS; } (codice schifoso, ma è giusto un test) |
|
![]() |
![]() |
![]() |
#18 | |||||||
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Quote:
Chi ti vieta di allocare con new un array di n byte??? Quote:
Quote:
Quote:
Quote:
![]() Sarà mica appunto che te usi il "C con le classi" invece del C++? Quote:
E se te sostieni che è meglio usare malloc forse è il caso di studiarsi un po' meglio il C++, oppure limitarsi a parlare di C. |
|||||||
![]() |
![]() |
![]() |
#19 | |||
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Inutile continuare con la pessima abitudine di usare malloc in C++. Quote:
![]() Data la documentazione mi pare ovvio: Quote:
|
|||
![]() |
![]() |
![]() |
#20 | ||
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Sul serio, pensavo fosse default. Ma poi un bug mi ha fatto cambiare idea. Non lo so, magari lo fa "a volte"
![]() Bisognerebbe indagare... @tomminno Prima di tutto, c'è da dire che uso C/C++ perchè è multipiattaforma, e perchè ha più librerie compatibili di qualsiasi altro linguaggio esistente... il che rende molto difficile usare allo stesso tempo degli "advanced tricks" di C++ senza complicarsi la vita con librerie di terzi. ad esempio la std è piuttosto oscena, e preferisco non usarla. A parte che è lenta, a parte che genera errori incomprensibili, ha anche il problema che non è usata da circa nessuna libreria di terze parti, almeno nel mio ambito. Alcuni esempi: -OpenGL -DirectX -Win32 -OpenAL -Box2D -Havok -PhysX -CUDA -Qt -l'iphone -android NDK in sostanza, quelle librerie che esistono in C/++ per le sue performance, o per la compatibilità con C in genere NON usano STL; di conseguenza se i dati interni al programma sono immagazzinati in contenitori STL, tutto il codice di interazione diventa un cast, una copia, o peggio... e questo perchè STL ha solo contenitori opachi. L'unico tipo veramente usato di STL è la stringa, quella si salva... ma in generale la situazione è completamente diversa da Java, e STL fallisce proprio perchè è tutto tranne che standard. Ovviamente esistono ambiti dove le performance non contano, ma allora li è da malati usare C++ e basta... I templates complicano la vita sostanzialmente a causa del compilatore, ad esempio in quei casi quando 2 template devono includersi a vicenda. Bellissimo ![]() Inoltre come sopra generano errori assurdi e uccidono il tempo di compilazione, che per progetti grandi E' importante. Diverse strutture nei miei progetti non si potrebbero fare senza template, intendiamoci... ma vanno usati con attenzione e non come fa STL o Boost, perchè a tutti gli effetti sono una feature buggata. Quote:
Mi stai paragonando Codice:
void* data = (void*)new char[ size ]; Codice:
void* data = malloc(size); Poi se vuoi usarlo come malloc si può fare, ma per me confonde e basta. Quote:
![]() Comunque sto sito, anche se esagera, fa comunque capire come la penso quando parlo di "inconsistenze" ![]() Ultima modifica di Tommo : 05-04-2011 alle 01:17. |
||
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:21.