2016-01-10 2 views
5

У меня возникла проблема, когда я пытаюсь прочитать char* professeur в двоичном файле, который он терпит неудачу, что дает мне ошибку сегментации в функции read(). Что странно, так это то, что для всех остальных функций load в других классах для чтения char* члены работают нормально, но для этого, даже если professeur написан правильно, у меня есть ошибка seg.C++ - бинарный файл с ошибками сегментации

Так вот код:

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&); 
}; 

Cours.cpp

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

Что делает 'соиЬ << "п:" << п << Endl;' сказать? Вы читаете мимо буфера? –

+0

n дает длину файла профессора в файле, и он дает его правильно.Нет, длина теста, который я использовал, была 14, поэтому нет совсем нет. –

+0

Вы пробовали отладку? – Koshinae

ответ

3

n следует проверить, чтобы убедиться, что он не получает больше, чем буфер ,

В save():

int n=strlen(professeur); 

n должна быть не более 59 здесь - должно быть проверено.

В load():

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

Лучше проверить n здесь (макс 59).

также:

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

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

Два разных значения используются для записи данных: strlen(professeur), а затем getProfesseur().

Вы также не выделяете память для professeur (по крайней мере, не в показанном коде). Таким образом, strcpy(professeur, buff); в load() тоже потерпит неудачу.

Вы могли бы также изменить:

private: 
    char* professeur; 

в

private: 
    char professeur[60]; 

Таким образом, вы не должны allocate и deallocate памяти самостоятельно.

И убедитесь, что все строки имеют нулевое завершение.

Конечно, если упражнение позволяет, вы можете использовать вместо string (string professeur;), и поток данных в и с использованием << и >>.

+0

Я проверил его на загрузке, и все в порядке, поэтому я не проверял его в сохранении. Нужно ли мне ? –

+0

@RemiHirtz - Да, всегда проверяйте. Также проверьте мое обновление. –

+0

Итак, я проверил n в сохранении и загрузке, и значение правильно (14 для моего теста), и я заменил 'getProfesseur()' на 'professeur'. Но я все еще получаю ошибку сегментации: s –

2

Сначала вы прочтете длину имени. Allocat как много char как длинное имя +1 для /0, право на цель. Чтение из файла, чтобы цели и добавить \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); 
} 
Смежные вопросы