|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
[C] Allocazione dinamica e problema con free
Salve a tutti, continuo ad avere un problema con il comando free quando vado a liberare la memoria di una matrice. Al momento ho riscritto tutto il programma ed ho messo solo la parte dell'allocazione dinamica della memoria per vedere dov'era l'errore. Il programma deve leggere un file di 7 colonne con un numero di righe non noto. Dopo di che lo salva.
Quello che ho scritto io fa esattamente questo ma se alla fine vado a liberare la memoria si blocca. ![]() ![]() Perché ![]() Gtrazie ![]() Il codice è il seguente e senza il free finale con MSVC funziona Codice:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <float.h> #define nomefile "OUTPUT.DAT" struct mydata { double **matrice; double INFO[10]; double **uscite; int step; }; int leggi(struct mydata *dati) { FILE *fdati; int t; int punti=20; printf("Numero dipunti da leggere %d\nLettura - ",punti); if((fdati=fopen(nomefile,"r"))==NULL) printf("Impossibile aprire il file"); else { t=0; while(fscanf(fdati,"%LE %LE %LE %LE %LE %LE %LE",&dati->matrice[t][0],&dati->matrice[t][1],&dati->matrice[t][2],&dati->matrice[t][3],&dati->matrice[t][4],&dati->matrice[t][5],&dati->matrice[t][6])>0) { if(t>=punti) break; t++; } } fclose(fdati); printf("OK\n"); return t; } int salva(struct mydata *data) { FILE *fsalva; int i,t,punti; punti=data->step; if((fsalva=fopen("STORIA.dat","w"))==NULL) printf("Impossibile scrivere\n"); else { for(t=0;t<punti;t++) { for(i=0;i<7;i++) { fprintf(fsalva,"%.4LE\t",data->matrice[t][i]); } fprintf(fsalva,"\n"); } } return 1; } int main() { int colonne, righe, tempo; int t,j; struct mydata insieme; system("cls"); colonne=7; righe=30; insieme.matrice = (double **)malloc(righe*sizeof(double *)); for(t=0;t<righe;t++) insieme.matrice[t] = (double *)malloc(colonne*sizeof(double *)); tempo=leggi(&insieme); insieme.step=tempo; for(t=0;t<tempo;t++) { for(j=0;j<3;j++) printf("M[%2d][%d]=%2.3g\t",t+1, j+1, insieme.matrice[t][j]); printf("\n"); } salva(&insieme); /*for(t=0;t<tempo;t++) free(insieme.matrice[t]); free(insieme.matrice); system("PAUSE");*/ return 1; }
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Manca il file OUTPUT.DAT per testarlo.
Comunque hai sbagliato l'allocazione L'allocazione nel for non è da fare con "sizeof(double *)" , ma con "sizeof(double)" Saluti
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
O meglio non va sotto linux. Nella versione precedente anche con sizeof(double *) sotto XP con MSVC andava e si bloccava solo al comando free mentre con linux mi da dei risultati sbagliati anche facendo la correzione. Anche qui se metto free si blocca. ![]() ![]() ![]() Grazie PS Posto qualche riga del file OUTPUT.dat se ti va di testare Codice:
0.00000E+00 0.00000E+00 0.36077E+01 0.00000E+00 0.47400E+02 0.39976E+01 0.90246E+00 0.20000E+00 0.72153E+00 0.36076E+01 -0.15438E-03 0.47395E+02 0.39975E+01 0.90247E+00 0.40000E+00 0.14431E+01 0.36076E+01 -0.18149E-03 0.47395E+02 0.39975E+01 0.90246E+00 0.60000E+00 0.21646E+01 0.36076E+01 -0.18065E-03 0.47395E+02 0.39975E+01 0.90245E+00 0.80000E+00 0.28861E+01 0.36075E+01 -0.17686E-03 0.47395E+02 0.39978E+01 0.90238E+00 0.10000E+01 0.36076E+01 0.36075E+01 -0.15387E-03 0.47397E+02 0.39982E+01 0.90228E+00 0.12000E+01 0.43291E+01 0.36075E+01 -0.11592E-03 0.47400E+02 0.39990E+01 0.90209E+00 0.14000E+01 0.50506E+01 0.36075E+01 -0.50029E-04 0.47405E+02 0.40001E+01 0.90184E+00 0.16000E+01 0.57721E+01 0.36075E+01 0.45672E-04 0.47412E+02 0.40016E+01 0.90151E+00 0.18000E+01 0.64936E+01 0.36075E+01 0.17416E-03 0.47421E+02 0.40034E+01 0.90111E+00 0.20000E+01 0.72151E+01 0.36076E+01 0.33128E-03 0.47431E+02 0.40057E+01 0.90061E+00 0.22000E+01 0.79366E+01 0.36077E+01 0.52640E-03 0.47444E+02 0.40083E+01 0.90005E+00
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13826
|
Tu usi %LE nella scanf che indica un "long double" , mentre nella matrice usi dei "double".
Prova a sostituire tutti i "double" con dei "long double" vedrai che funzionerà. Ricordati di eseguire la stessa modifica anche nelle "malloc". (e di non mettere il "*" nella malloc del for). Non so bene quale sia la dinamica dell'errore. Forse la scrittura in formato sbagliato della scanf in memoria causa una corruzione che poi , all'atto della free, causa un segmentation fault. Probabilmente alcuni dati di controllo delle Glibc vengono sovrascritti ... sto sparando a caso ovviamente perchè non so con precisione come le glibc gestiscano a basso livello allocazioni e deallocazioni ![]() Ciao
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
![]() Il problema era proprio quello. Con MSVC probabilmente forzava l'allocazione della memoria in modo tale che fosse long double ma quando la liberavo si incasinava tutto. Sotto linux invece non facendo questa operazione il programma si piantava subito. L'avessi fatto subito da qui mi sarei risparmiato 10 giorni dimal di testa. Tutto è bene quel che finisce bene ![]() ![]() ![]() potevo rimanere gravemente offeso ![]()
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:18.