简体   繁体   中英

C++ - segmentation fault reading binary file

I got an issue, when I try to read char* professeur in a binary file it fails, giving me a segmentation fault in the read() function. What's weird is that for all other load function in other classes to read char* members works just fine but for this one, even if the professeur is written correctly in the I got a seg fault.

So here is the code:

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

n should be checked to make sure it doesn't get larger than the buffer.

In save() :

int n=strlen(professeur);

n should be max 59 here - needs to be checked.

In load() :

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

Better check n here too (max 59).

Also:

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

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

Two different values are used to write the data: strlen(professeur) and then getProfesseur() .

You also don't allocate memory for professeur (at least not in the shown code). So strcpy(professeur, buff); in load() will fail too.

You might as well change:

private:
    char* professeur;

to

private:
    char professeur[60];

That way you don't have to allocate and deallocate memory yourself.

And make sure all strings are null-terminated.

Of course , if the exercise allows it, you can use string instead ( string professeur; ), and stream the data in and out using << and >> .

First you read the length of the name. Allocat as many char as the name is long +1 for /0 , right to target. Read from file to target and append \\0 at the end:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM