2017-10-17 4 views
-3

Donc, je viens de commencer à utiliser Ubuntu récemment. Je construis ce programme très simple qui me permettra de stocker des données et de les relire plus tard. En utilisant C++, fstream, certains objets sont stockés dans un fichier .dat.Impossible de lire le fichier .dat ou .bin dans Ubuntu "Erreur de segmentation (core dumped)"

// function to store 
void storeRecord(Record r){ 
    fstream afile; 
    afile.open("file.dat" , ios::out | ios::binary | ios::app); 
    afile.write(reinterpret_cast <const char*> (&r), sizeof(r)); 
    afile.close(); 
} 

Mais lorsque je tente de (appel requête() fonction) lecture du même fichier, que je reçois "Segmentation fault (core dumped)"

void query(){ 
     Record r; 
     fstream afile; 
     afile.open("file.dat", ios::in | ios::binary); 
     while(afile.read(reinterpret_cast <char*> (&r), sizeof(r))){ 
      // do something 
     } 
     afile.close(); 
} 

Cette habitude de travailler sur les fenêtres. Pourquoi donc?

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

class Record{ 
public: 
    // Constructors 
    Record(); 
    Record(string accountID, string name, string deptID, string password,   int role); 
    ~Record(); 

    // Assessors and Mutators 
    string getAccountID(); 
    string getName(); 
    string getDeptID(); 
    string getPW(); 
    int getRole(); 

    void setAccountID(string accountID); 
    void setName(string name); 
    void setDeptID(string deptID); 
    void setPW(string PW); 
    void setRole(int role); 

    // Other functions 
    string toString(); 

private: 
    string accountID; 
    string name; 
    string deptID; 
    string password; 
    int role;  // normal user, HR personal, admin 
}; 
+5

Il n'y a pas de r dans la requête définie. Qu'est-ce que Record? Si ce n'est pas un POD, vous avez votre bug. –

+0

Il y a. Dans le programme actuel. Mon erreur ici. oops – poh

+1

Quel est le type de 'Record'?A-t-il du [vtable] (https://en.wikipedia.org/wiki/Virtual_method_table), ou un pointeur (même indrect ou interne)? ** Votre code a [comportement indéfini] (https://en.wikipedia.org/wiki/Undefined_behavior) ** donc vous avez de la chance qu'il se bloque sur Linux (et * malchanceux * qu'il "semble" fonctionner sous Windows) .... –

Répondre

1

Votre Record contient std::string champs. Un string contient certainement des pointeurs et pourrait contenir des données internes avec des fonctions virtuelles (ayant ainsi un vtable, qui est un pointeur caché); alors que les données ont des pointeurs. Et un string est et non un POD (mais un tableau fixe de char serait, par exemple, un champ comme char name[48]; ....).

Ainsi, votre code a undefined behavior donc vous êtes chanceux qu'il crashes sur Linux (et malchanceux qu'il « semble » travailler sur Windows) ... BTW, quand il est apparemment « en cours d'exécution » (par exemple Windows) le format de fichier reste "indéfini" et vous ne pourrez pas relire un fichier de données écrit par une ancienne version de votre programme (ou même la même source compilée par un compilateur plus ancien ou différent et une bibliothèque standard C++).

Linux a ASLR; cela pourrait expliquer pourquoi vous avez un segmentation fault. BTW, je suppose que Linux pourrait ne pas planter si vous écrivez et lisez le même fichier de données dans le mêmeprocess (ce qui n'est pas particulièrement utile pour vous).

Pour en savoir plus, vous devrez vous plonger dans les détails d'implémentation, et vous ne le souhaitez pas.

Apparemment, vous devez installer des machines serialization. Puis spécifiez d'abord (et en détails) votre file format (octet par octet, endianness et "taille de mot" et votre format de fichier devrait être "indépendant" d'eux), en utilisant peut-être EBNF notation. Ensuite, implémentez les routines de sérialisation, en commençant par les types élémentaires POD. Ou utilisez une bibliothèque de sérialisation. Votre format de fichier et votre code doivent être portables (par exemple, le même programme sur Raspberry Pi et sur Linux/PC devrait pouvoir échanger des fichiers de données). Par ailleurs, je préfère beaucoup utiliser un format textuel, en utilisant peut-être JSON, YAML (ou XML). Ou considérer aussi des bibliothèques comme SQLite ou GDBM. Dans votre cas, votre Record peut être facilement mappé sur des lignes dans des tables SQLite ou des objets JSON. Vous devriez peut-être demander à votre enseignant si vous êtes autorisé à les utiliser ....