2016-01-10 19 views
5

char* professeurをバイナリファイルで読み込もうとすると、問題が発生します。これは失敗し、read()関数でセグメント化エラーが発生します。奇妙なのは他のクラスの他のクラスのload関数を読み取ると、char*のメンバーはうまく動作しますが、この場合はprofesseurが正しく書かれていても、segフォルトが発生します。だからここC++ - セグメンテーションエラーバイナリファイルを読み込む

はコードです:Cours.cpp

Cours.h

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iostream> 

using namespace std; 

#include "Liste.h" 
#include "Event.h" 
#include "Professeur.h" 

class Cours: public Event 
{ 
    private: 
     char* professeur; 
     Liste<int> groupes; 
    public: 
     void save(ofstream&) const; 
     void load(ifstream&); 
}; 

void Cours::save(ofstream& o) const 
{ 
    int n=strlen(professeur); 
    char buff[60], *buff2; 

    o.write((char *)&n, sizeof(int)); 
    strcpy(buff, getProfesseur()); 
    o.write(buff, n+1); 

    groupes.save(o); 
    Event::save(o); 
} 

void Cours::load(ifstream& i) 
{ 
    int n; 
    char buff[60]; 

    i.read((char *)&n, sizeof(int)); 
    cout<<"n: "<<n<<endl; 
    if(i.read(buff, n+1))//seg fault 
    { 
     strcpy(professeur, buff); 
     cout<<"prof: "<<professeur<<endl;  
    } 
    else 
     cout<<"erreur read prof cours"<<endl; 
    groupes.load(i); 
    Event::load(i); 
} 
+0

「cout <<」n:「<< n << endl;」とは何ですか?あなたはバッファを過ぎて読んでいますか? –

+0

nはファイル内のprofesseurの長さを与え、正しく与えます。いいえテストの長さは私が使用した14だったので全くありません –

+0

あなたはデバッグを試みましたか? – Koshinae

答えて

3
nは、それがバッファより大きくわから取得していないにするためにチェックする必要があります

save()

int n=strlen(professeur); 

nがここに最大59でなければなりませんが - をチェックする必要があります。 load()

i.read((char *)&n, sizeof(int)); 

より良いここにチェックnすぎ(最大59)。

はまた:strlen(professeur)、その後getProfesseur()

int n=strlen(professeur); 
char buff[60], *buff2; 

o.write((char *)&n, sizeof(int)); 
strcpy(buff, getProfesseur()); 
o.write(buff, n+1); 

2つの異なる値は、データを書き込むために使用されています。

professeurのメモリも割り当てられません(少なくとも図示のコードには含まれていません)。だからload()strcpy(professeur, buff);も失敗します。あなたはallocatedeallocateメモリに自分自身を持っていない道

private: 
    char* professeur; 

private: 
    char professeur[60]; 

へ:

あなたが同様に変更される場合があります。

そして、すべての文字列がNULLで終了することを確認してください。もちろんの

、運動がそれを可能にする場合は、代わりに(string professeur;stringを使用し、中と<<>>を使用してデータをストリーミングすることができます。

+0

私はそれをチェックしました。それは大丈夫です。したほうがいい ? –

+0

@RemiHirtz - はい、常にチェックしてください。また、私の更新をチェックしてください。 –

+0

私はsaveとloadでnをチェックして、値が正しい(私のテストでは14)と、 'professeur'によって' getProfesseur() 'を置き換えました。しかし、私はまだセグメンテーションフォールトを取得しています。■ –

2

まず、名前の長さを読んでください。 Allocat as many 名前は/0の長い+1です。ファイルから読み込み、末尾に\0を追加してください。

void Cours::load(ifstream& i) 
{ 
    int n; 
    i.read((char *)&n, sizeof(int)); 
    cout<<"n: "<<n<<endl; 
    if (n <= 0) 
     return; 

    professeur = new char[n+1];    // allocate professeur 
    if (i.read(professeur, n))   // read directly to professeur 
    { 
     professeur[ n ] = ´\0`;    // write \0 at end of name 
     cout<<"prof: "<<professeur<<endl; 
    } 
    else 
    { 
     delete [] professeur; 
     professeur = nullptr; 
     cout<<"erreur read prof cours"<<endl; 
    } 

    groupes.load(i); 
    Event::load(i); 
} 
関連する問題