2016-01-10 35 views
5

Tôi gặp sự cố, khi tôi cố gắng đọc char* professeur trong tệp nhị phân không thành công, cho tôi lỗi phân đoạn trong hàm read(). Điều kỳ lạ là đối với tất cả các hàm load khác trong các lớp khác để đọc char* thành viên chỉ hoạt động tốt nhưng đối với thành viên này, ngay cả khi professeur được viết chính xác trong tôi đã nhận được lỗi seg.C++ - lỗi phân đoạn đọc tệp nhị phân

Vì vậy, đây là mã:

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

'cout <<" n: "<< n << endl;' nói gì? Bạn đang đọc qua bộ đệm? –

+0

n cho độ dài của professeur trong tập tin, và nó cho nó một cách chính xác.Không có độ dài của bài kiểm tra I useg là 14 vì vậy không có không ở tất cả –

+0

Bạn đã thử gỡ lỗi chưa? – Koshinae

Trả lời

3

n nên được kiểm tra để chắc chắn rằng nó không nhận được lớn hơn so với đệm .

Trong save():

int n=strlen(professeur); 

n nên max 59 đây - cần được kiểm tra.

Trong load():

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

Better séc n đây quá (tối đa 59).

Ngoài ra:

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

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

Hai giá trị khác nhau được sử dụng để ghi dữ liệu: strlen(professeur) và sau đó getProfesseur().

Bạn cũng không cấp phát bộ nhớ cho professeur (ít nhất không phải trong mã được hiển thị). Vì vậy, strcpy(professeur, buff); trong load() cũng sẽ không thành công.

Bạn cũng có thể thay đổi:

private: 
    char* professeur; 

để

private: 
    char professeur[60]; 

Bằng cách đó bạn không cần phải allocatedeallocate bộ nhớ chính mình.

Và đảm bảo tất cả các chuỗi đều bị hủy.

Tất nhiên, nếu tập thể dục cho phép nó, bạn có thể sử dụng thay vì string (string professeur;), và dòng dữ liệu vào và ra bằng <<>>.

+0

Tôi đã kiểm tra nó trong tải và nó là ok, vì vậy tôi đã không kiểm tra nó trong lưu. Tôi có nên không? –

+0

@RemiHirtz - Có, luôn kiểm tra. Đồng thời kiểm tra cập nhật của tôi. –

+0

Ok vì vậy tôi đã kiểm tra lưu và tải và giá trị là chính xác (14 cho thử nghiệm của tôi) và tôi đã thay thế 'getProfesseur()' bằng 'professeur'. Nhưng tôi vẫn nhận được lỗi phân đoạn: s –

2

Trước tiên, bạn đọc chiều dài của tên. Allocat với số lượng là char là tên +1 dài cho /0, phải nhắm mục tiêu. Đọc từ tệp để nhắm mục tiêu và nối thêm \0 vào cuối:

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); 
} 
Các vấn đề liên quan