lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Postato originariamente da Mikelius:
Postato originariamente da lumo:
Così è di sicuro sbagliata, perché se il file contiene 10 caratteri, tu allocherai una stringa di 10 char, ma te ne servono 11 per avere anche il terminatore finale.
Usare realloc in questo caso non ha senso, fa direttamente una singola allocazione con malloc o calloc una volta che hai ottenuto la dimensione del file (vantaggio scontato: un punto solo in cui malloc può fallire invece di due, uno sul primo calloc e l'altro su realloc).
|
non solo, ma eseguendo la realloc/calloc/malloc con :
Codice sorgente - presumibilmente Plain Text |
non si sta allocando uno spazio 4 volte maggiore rispetto al necessario?
quindi non "si nota" il +1 a dim mancante, perche in realta la dimensione allocata è 4x(*dim) e non (*dim)
o sbaglio? i puntatori sono gestiti da 4 byte per indirizzo a prenscindere dal tipo, giusto? |
Hai proprio ragione, il codice corretto dovrebbe avere sizeof(char).
4 byte per indirizzo invece non è detto. Di fatto mi pare di ricordare che l'unica dimensione che lo standard garantisce è sizeof(char) == 1, ma le dimensioni dei puntatori possono essere differenti. Nella pratica, le architetture più comuni a 32 bit hanno puntatori di 4 byte, mentre quelle a 64bit hanno puntatori di 8 byte.
Mark22 c'è un motivo per cui usi unsigned char? Vuoi leggere un file binario? Ultima modifica effettuata da lumo il 30/10/2017 alle 18:57 |
|
mark22 (Normal User)
Newbie
Messaggi: 11
Iscritto: 29/10/2017
|
Vi ringrazio per l'ennesima volta.. si voglio poter leggere qualsiasi tipo di file.
Ma se utilizzassi array di unsigned int sarebbe ancora meglio giusto? Così evito la gestione del carattere terminatore
Ultima modifica effettuata da mark22 il 30/10/2017 alle 19:15 |
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Se vuoi leggere un file binario, ritorna ad aprire il file con "rb".
Salva il contenuto in un array (dinamico) di unsigned char (io preferisco usare uint8_t che si trova in <stdint.h>, in questi casi).
Il terminatore non serve visto che non si tratta di una stringa, però devi salvarti la lunghezza di ciò che hai letto da qualche parte.
Unsigned int non va bene qui.
|
|
mark22 (Normal User)
Newbie
Messaggi: 11
Iscritto: 29/10/2017
|
Postato originariamente da lumo:
Se vuoi leggere un file binario, ritorna ad aprire il file con "rb".
Salva il contenuto in un array (dinamico) di unsigned char (io preferisco usare uint8_t che si trova in <stdint.h>, in questi casi).
Il terminatore non serve visto che non si tratta di una stringa, però devi salvarti la lunghezza di ciò che hai letto da qualche parte.
Unsigned int non va bene qui. |
Potrei chiederti che differenza c'è tra unsigned char e uint8_t?? Non l'ho mai utilizzato il secondo.
Così va bene giusto?
Codice sorgente - presumibilmente C++ |
void apriFile(char *nomeFile,unsigned char** s, int *dim){ FILE *f; f=fopen(nomeFile,"rb"); if(f==NULL){ printf("\nErrore nell'apertura del file."); return; } if(*s!=NULL) free(*s); fseek(f, 0, SEEK_END); *dim=ftell(f); rewind(f); *s=(unsigned char*)malloc(*dim*sizeof(char)); if(*s==NULL){ printf("ERRORE!"); return; } else fread(*s,sizeof(char),*dim,f); fclose(f); }
|
Ultima modifica effettuata da mark22 il 30/10/2017 alle 20:13 |
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Se l'allocazione fallisce non raggiungerai fclose, questo va corretto.
Poi se si volesse essere proprio precisi bisognerebbe anche controllare che fread() abbia letto
|
|
mark22 (Normal User)
Newbie
Messaggi: 11
Iscritto: 29/10/2017
|
Ok perfetto per la fclose.. per la fwrite non dovrebbe esserci problema perchè quando determina la dimensione del file, in caso fosse 0, la malloc fallirebbe. Grazie davvero dei consigli mi siete stati davvero d'aiuto
|
|
Mikelius (Member)
Expert
Messaggi: 525
Iscritto: 14/04/2017
|
Postato originariamente da mark22:
....per la fwrite non dovrebbe esserci problema perchè quando determina la dimensione del file, in caso fosse 0, la malloc fallirebbe. Grazie davvero dei consigli mi siete stati davvero d'aiuto |
Non essere cosi sicuro delle funzioni, testare il valore di ritorno (che è utile inserire se la funzione potrebbe non essere svolta) è importante anche nelle printf() (ok, ho esagerato per questo programmino).
Prova ad eseguire il programma con diversi file, ad esempio; uno inestistente, uno vuoto, uno pieno ecc ecc. e guarda come si comporta il programma. (p.s. se passi argomenti da linea di comando, è bene testare che ci siano prima di utilizzarli, nel tuo main non ci sono i controlli) |
|