Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Segmentation Fault su lettura binaria di un file
Forum - C/C++ - Segmentation Fault su lettura binaria di un file

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
spitty_cash (Normal User)
Newbie


Messaggi: 8
Iscritto: 19/09/2010

Segnala al moderatore
Postato alle 10:43
Domenica, 19/09/2010
Salve a tutti,
vorrei un aiuto su questo tipo di errore...programmo sotto ambiente linux, ma questo errore è presente anche su windows, con compilatore MinGW g++.
Molto probabilmente l'errore è dato dalla mia ignoranza ma cio che non mi spiego è perchè usando il compilatore microsoft visual c++ non c'è nessun tipo di errore invece con MinGW mi da errore nella lettura del file(Segmentation fault)...e forse anche nella scrittura.
Praticamente questo programma scrive una struttura in un file binario e successivamente la va a leggere mandando in output su console i dati della struttura...vi posto il codice:
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4.  
  5. using namespace std;
  6.  
  7. int main()
  8. {
  9.     struct Contatto{ string nome; string cognome; };
  10.     Contatto Spitty;
  11.  
  12.     Spitty.nome="Nome_Spitty";
  13.     Spitty.cognome="Cognome_Spitty";
  14.  
  15.     //Scrittura Spitty su file
  16.     ofstream out;
  17.     out.open( "dati.rub", ios::out | ios::app | ios::binary );
  18.     out.write( (char*)&Spitty, sizeof(Spitty) );
  19.     out.close();
  20.  
  21.     //Cambio valori nella struttura ( per verificare che la funzione read abbia letto correttamente )
  22.     Spitty.nome="Vuoto";
  23.     Spitty.cognome="Vuoto";
  24.     cout<<endl;
  25.  
  26.  
  27.     //Visualizzazione struttura Spitty
  28.     cout<<"\nNome: "<<Spitty.nome;
  29.     cout<<"\nCognome: "<<Spitty.cognome;
  30.  
  31.  
  32.  
  33.     //Lettura valori nel file binario
  34.     ifstream in;
  35.     in.open( "dati.rub", ios::in | ios::binary );
  36.     in.read( (char*)&Spitty, sizeof(Spitty) );
  37.     in.close();
  38.  
  39.     //Visualizzazione struttura Spitty
  40.     cout<<"\nNome: "<<Spitty.nome;
  41.     cout<<"\nCognome: "<<Spitty.cognome;
  42.     cout<<endl;
  43.  
  44.  
  45.     return 0;
  46. }



Grazie per eventuali risposte!
Ciao a tutti.

Ultima modifica effettuata da spitty_cash il 19/09/2010 alle 11:00
PM
Avatar
Bonny (Member)
Expert


Messaggi: 437
Iscritto: 24/04/2009

Up
1
Down
V
Segnala al moderatore
Postato alle 11:17
Domenica, 19/09/2010
Nota: Se sei un GNU g + + utente (versione 2.7.x o precedenti), quindi non utilizzare i / le bandiere mode o durante l'apertura di oggetti ifstream. Because of a bug in the GNU libg++ implementation, the flags will not be correctly interpreted. A causa di un bug nel GNU libg + + attuazione, le bandiere non verrà interpretato correttamente. If you are working under Unix, omit the i/o mode flags entirely; if you are working with g++ under MS-DOS, then use an fstream object.  Se si lavora sotto Unix, omettere i / le bandiere mode o del tutto, se si lavora con g + + MS-DOS, quindi utilizzare un oggetto fstream. This note applies to g++ users only . La presente nota vale per gli utenti g + + solo.

Ho trovato questa nota leggendo questo tutorial :

http://www.angelfire.com/country/aldev0/cpphowto/cpp_Binar ...


Spero di esserti stato d'aiuto;)

Ultima modifica effettuata da Bonny il 19/09/2010 alle 11:21
PM
Avatar
spitty_cash (Normal User)
Newbie


Messaggi: 8
Iscritto: 19/09/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 13:11
Domenica, 19/09/2010
Allora...ho voluto provare subito...ne su linux ne su windows funziona il programma...anche non mettendo i mode flags e anche non dichiarando ifstream o ofstream ma semplicemente fstream...posto il codice che ho provato su linux:
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4.  
  5. using namespace std;
  6.  
  7. int main()
  8. {
  9.     struct Contatto{ string nome; string cognome; };
  10.     Contatto Spitty;
  11.  
  12.     Spitty.nome="Nome_Spitty";
  13.     Spitty.cognome="Cognome_Spitty";
  14.  
  15.     //Scrittura Spitty su file
  16.     ofstream out;
  17.     out.open( "dati.rub" );
  18.     out.seekp(0);
  19.     out.write( (char*)&Spitty, sizeof(Spitty) );
  20.     out.close();
  21.  
  22.     //Cambio valori nella struttura ( per verificare che la funzione read abbia letto correttamente )
  23.     Spitty.nome="Vuoto";
  24.     Spitty.cognome="Vuoto";
  25.     cout<<endl;
  26.  
  27.  
  28.     //Visualizzazione struttura Spitty
  29.     cout<<"\nNome: "<<Spitty.nome;
  30.     cout<<"\nCognome: "<<Spitty.cognome;
  31.  
  32.  
  33.  
  34.     //Lettura valori nel file binario
  35.     ifstream in;
  36.     in.open( "dati.rub" );
  37.     in.seekg(0);
  38.     in.read( (char*)&Spitty, sizeof(Spitty) );
  39.     in.close();
  40.  
  41.     //Visualizzazione struttura Spitty
  42.     cout<<"\nNome: "<<Spitty.nome;
  43.     cout<<"\nCognome: "<<Spitty.cognome;
  44.     cout<<endl;
  45.  
  46.     return 0;
  47. }


Chiedo aiuto a qualche programmatore che sviluppa su linux e che sicuramente usa GNU MinGW g++...grazie

Ultima modifica effettuata da spitty_cash il 19/09/2010 alle 14:33
PM
Avatar
Bonny (Member)
Expert


Messaggi: 437
Iscritto: 24/04/2009

Up
0
Down
V
Segnala al moderatore
Postato alle 13:28
Lunedì, 20/09/2010
Di niente figurati:k:

PM
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 14:01
Lunedì, 20/09/2010
il problema è nella read, non puoi leggere una struttura con due string così...
dovresti fare
Codice sorgente - presumibilmente C/C++

  1. out << Spitty.nome << Spitty.cognome;
  2. /* ... */
  3. in >> Spitty.nome >> Spitty.cognome;


PM
Avatar
spitty_cash (Normal User)
Newbie


Messaggi: 8
Iscritto: 19/09/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 17:12
Lunedì, 20/09/2010
che palle lo sapevo che andava a finire così...lumo nn mi va di incazzarmi solamente perchè tu non conosci il c++...apri un qualsiasi libro di testo sul c++ e studiati come funziona l'accesso sequenziale/diretto agli archivi con record a lunghezza costante ( in gergo scrivi su un file binario una struttura dati ).
Cioè è pazzesco...ti sto dicendo che quel codice con visual c++ funziona e tu mi dici che devo scrivere con gli operator << >> ??? Guardati la libreria fstream invece di scrivere cavolate.
Anzi testa il codice su visual c++ e accorgiti di non saper scrivere archivi a record di lunghezza costante.

Ultima modifica effettuata da spitty_cash il 20/09/2010 alle 17:14
PM
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 22:42
Lunedì, 20/09/2010
Testo quotato

Postato originariamente da spitty_cash:
Cioè è pazzesco...ti sto dicendo che quel codice con visual c++ funziona e tu mi dici che devo scrivere con gli operator << >> ??? Guardati la libreria fstream invece di scrivere cavolate.


hai ragione, farò proprio così
http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USE ...
[string.h]
Codice sorgente - presumibilmente Delphi

  1. template<typename _CharT, typename _Traits, typename _Alloc>
  2.     inline basic_ostream<_CharT, _Traits>&
  3.      operator<<(basic_ostream<_CharT, _Traits>& __os,
  4.             const basic_string<_CharT, _Traits, _Alloc>& __str)
  5.      {
  6.        // _GLIBCXX_RESOLVE_LIB_DEFECTS
  7.        // 586. string inserter not a formatted function
  8.        return __ostream_insert(__os, __str.data(), __str.size());
  9.      }


[ostream_insert.h]
http://www.pierotofy.it/pages/users/copypastebin/viewCode. ...
come vedi dal sorgente la funzione usa ostream::write, quindi la scrittura formattata può essere usata benissimo con file aperti in modalità binaria. E ora: perchè write non va su g++.
Il fatto è che, supponendo che la std::string abbia un'implementazione simile nella libstdc++
Codice sorgente - presumibilmente C#

  1. struct string
  2. {
  3.     char* m_buf;
  4.  
  5.     /* ... */
  6.  
  7.     void operator=( const char* data )
  8.     {
  9.          uint32 len = strlen(data);
  10.          m_buf = Allocator.alloc(len+1);
  11.          strcpy( m_buf, data, len );
  12.     }
  13. };


quando fai un cast del genere (char*)&stringa, non ottieni i dati della stringa sottoforma di C string, ma l'indirizzo del puntatore, non so se mi spiego.
Quindi alla fine, quando vai a fare write(), non stampi i veri dati ma solo un indirizzo. Non so perchè su MSVC funzioni, ma manvb.net ha guardato e pensa che l'implementazione di msvc usi un buffer statico per memorizzare i dati( mi pare strano ma boh ).

E poi, arrabbiati quanto vuoi, ma questo forum è aperto e se qualcuno vuole aiutarti e pensa di avere la soluzione al tuo problema è libero di postare. Io ho addirittura provato il tuo programma, ora ti ho anche dato una spiegazione, e lo farò finchè sarò convinto di avere ragione. Se riuscirai a dimostrarmi il contrario su g++, allora ok, ma intanto accontenati di chi cerca di aiutarti, perchè qui nessuno viene pagato per darti le risposte.

Ultima modifica effettuata da lumo il 20/09/2010 alle 23:26
PM
Avatar
spitty_cash (Normal User)
Newbie


Messaggi: 8
Iscritto: 19/09/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 12:13
Martedì, 21/09/2010
Testo quotato

Postato originariamente da lumo:

Testo quotato

Postato originariamente da spitty_cash:
Cioè è pazzesco...ti sto dicendo che quel codice con visual c++ funziona e tu mi dici che devo scrivere con gli operator << >> ??? Guardati la libreria fstream invece di scrivere cavolate.


hai ragione, farò proprio così
http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USE ...
[string.h]
Codice sorgente - presumibilmente Delphi

  1. template<typename _CharT, typename _Traits, typename _Alloc>
  2.     inline basic_ostream<_CharT, _Traits>&
  3.      operator<<(basic_ostream<_CharT, _Traits>& __os,
  4.             const basic_string<_CharT, _Traits, _Alloc>& __str)
  5.      {
  6.        // _GLIBCXX_RESOLVE_LIB_DEFECTS
  7.        // 586. string inserter not a formatted function
  8.        return __ostream_insert(__os, __str.data(), __str.size());
  9.      }


[ostream_insert.h]
http://www.pierotofy.it/pages/users/copypastebin/viewCode. ...
come vedi dal sorgente la funzione usa ostream::write, quindi la scrittura formattata può essere usata benissimo con file aperti in modalità binaria. E ora: perchè write non va su g++.
Il fatto è che, supponendo che la std::string abbia un'implementazione simile nella libstdc++
Codice sorgente - presumibilmente C#

  1. struct string
  2. {
  3.     char* m_buf;
  4.  
  5.     /* ... */
  6.  
  7.     void operator=( const char* data )
  8.     {
  9.          uint32 len = strlen(data);
  10.          m_buf = Allocator.alloc(len+1);
  11.          strcpy( m_buf, data, len );
  12.     }
  13. };


quando fai un cast del genere (char*)&stringa, non ottieni i dati della stringa sottoforma di C string, ma l'indirizzo del puntatore, non so se mi spiego.
Quindi alla fine, quando vai a fare write(), non stampi i veri dati ma solo un indirizzo. Non so perchè su MSVC funzioni, ma manvb.net ha guardato e pensa che l'implementazione di msvc usi un buffer statico per memorizzare i dati( mi pare strano ma boh ).

E poi, arrabbiati quanto vuoi, ma questo forum è aperto e se qualcuno vuole aiutarti e pensa di avere la soluzione al tuo problema è libero di postare. Io ho addirittura provato il tuo programma, ora ti ho anche dato una spiegazione, e lo farò finchè sarò convinto di avere ragione. Se riuscirai a dimostrarmi il contrario su g++, allora ok, ma intanto accontenati di chi cerca di aiutarti, perchè qui nessuno viene pagato per darti le risposte.


lumo io ti ringrazio per la risposta, ma io devo scrivere su file una struttura...non devo scrivere e leggere una singola stringa in un file binario...cmq se hai la soluzione a questa cosa postala e vediamo.

PM
Avatar
spitty_cash (Normal User)
Newbie


Messaggi: 8
Iscritto: 19/09/2010

Up
-1
Down
V
Segnala al moderatore
Postato alle 14:41
Lunedì, 20/09/2010
Testo quotato

Postato originariamente da lumo:

il problema è nella read, non puoi leggere una struttura con due string così...
dovresti fare
Codice sorgente - presumibilmente C/C++

  1. out << Spitty.nome << Spitty.cognome;
  2. /* ... */
  3. in >> Spitty.nome >> Spitty.cognome;



lumo grazie per la risposta,
purtroppo quello che dici è scorretto...nel c++ posso leggere una struttura tramite un read(); gli passo la struttura e il suo size...e naturalmente su Microsoft Visual C++ 2008/2010 funziona tutto alla perfezione...l'avevo detto anche sopra che con Visual C++ funzionavano i metodi.
Quello che hai scritto tu è forse la sintassi per scrivere e leggere da file di testo tipo *.txt senza alcuna struttura. Mentre qui si parla di file binari!
Per rispondere bisogna conoscere gli stream di tipo fstream e i relativi metodi...altrimenti così si dicono solo cavolate e non si va da nessuna parte!
RIPETO: IN VISUAL C++ 2010 FUNZIONA TUTTO...MENTRE UTILIZZANDO IL COMPILATORE MINGW G++ C'E' UNA SEGMENTATION FAULT O ERRORI SIA IN SCRITTURA CHE IN LETTURA...MINGW SIA SU WINDOWS CHE SU LINUX.
Esperti rispondete!

PM
Pagine: [ 1 2 ] Precedente | Prossimo