Lỗi truyền tham chiếu và đọc ghi file nhị phân

a/c cho em hỏi, sao em đọc ghi file bài này bằng kiểu nhị phân thì không được mà em đọc kiểu text lại được, em nghe đồn là liên quan đến con trỏ ạ. Còn phần nạp chồng toán tử + để cộng 2 danh sách sao lúc truyền tham chiếu phải truyền bằng tham biến, nếu truyền tham trị thì không được ạ.

#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
class sinhvien{
	private:
		long ma;
		char ten[8];
	public:
		void set_ma(int x){ ma=x;
		}
		long get_ma(){ return ma;
		}
		void set_ten(char x[]){ strcpy(ten,x); 
		}
		char *get_ten(){ return ten;
		}
		void nhap(){
			cin.getline(ten,8);
			cin>>ma; cin.ignore();
		}
		void xuat(){
			cout<<ten<<" "<<ma<<endl;
		}
};
struct node{
	sinhvien info;
	node *next;
};
node *khoitaonode(sinhvien x){
	node *p=new node;
	p->info.set_ma(x.get_ma());
	p->info.set_ten(x.get_ten());
	p->next=NULL;
	return p;
}
class danhsach{
	private:
		node *pfirst;
		node *plast;
	public:
		friend danhsach operator+(danhsach &a, danhsach &b);
		danhsach(){
			pfirst=NULL;
			plast=NULL;
		}
		void themcuoi( sinhvien x){
			node *p= khoitaonode(x);
			if(pfirst==NULL) pfirst=plast=p;
			else {
				plast->next=p;
				plast=p; 
			}
		}
		void ghitep(){
			ofstream file("4.dat",ios::binary);
			file.write(reinterpret_cast <char*> (this),sizeof(danhsach));
			file.close();
		}
		void doctep(){
			ifstream file("4.dat",ios::binary);
			file.read(reinterpret_cast <char*> (this),sizeof(danhsach));
			file.close();
		}
		~danhsach(){
			ghitep(); 
			for(node *k=pfirst; k!=NULL;k=pfirst){
			    pfirst=k->next;	 
			    delete k;
			}
		}
};
danhsach operator+(danhsach &a, danhsach &b){
	danhsach c;  node *k;
	for(k=a.pfirst; k!=NULL;k=k->next){
			    c.themcuoi(k->info);
	}
	for(k=b.pfirst; k!=NULL;k=k->next){
			    c.themcuoi(k->info);
	}
	return c;
}
main(){
	danhsach a,b;  sinhvien x; node *p; 
	for(int i=0;i<4;i++){
		x.nhap();
		p=khoitaonode(x); 
		a.themcuoi(p->info); 
    }
    a.ghitep();  
    b.doctep();
    b.xemmh();
}

Mình vẫn đọc được mà. :thinking:

Cơ mà bạn ghi vô file chỉ có giá trị của pfirstplast thôi, chứ không phải ghi cả danh sách. :slight_smile:


Tham chiếu bản chất là con trỏ (hằng con trỏ). :slight_smile:

Nên truyền vô phải là địa chỉ của biến (mặc dù chuyền vô chỉ có tên biến không thôi nhưng compiler đã làm phần lấy địa chỉ cho bạn rồi, không cần phải & như dùng con trỏ) chứ không phải là giá trị. :smile:

2 Likes

pfirst và plast là 2 con trỏ mà lưu xuống file thì sau khi backup ngược lên thì vùng dữ liệu nó đã mất nên ăn hành là đúng rồi.

2 Likes

Chỉ lưu data thôi bạn :slight_smile: phần liên kết không còn ý nghĩa gì sau khi kết thúc chương trình.

2 Likes

Back up ngược lên là sao anh ?

Khi mình bỏ & đi chương trình chạy toàn báo lỗi, ý mình là sao phải dùng & thì chương trình mới chạy đúng, trong khi mình không cần thay đổi gì ở danhsach a và danhsach b ạ. Kiểu sao phải truyền tham chiếu trong khi mình không cần thay đổi giá trị bên trong của cả 2 danhsach truyền vào, mình dùng tham trị thì không chạy được

Bạn nói phần nào nhờ

Bạn có 2 con trỏ trong lớp danhsach và bạn lưu nó xuống file.
Giả dụ trước khi lưu thì 2 con trỏ này trỏ đến địa chỉ 0x0001 và 0x0002 đang chứa dữ liệu của danhsach.

Sau khi lưu 2 con trỏ này xuống và đọc ngược lại (backup) thì 2 con trỏ của danhsach mới cũng sẽ có địa chỉ 0x0001 và 0x0002. Nhưng dữ liệu nằm tại 2 địa chỉ này đã mất (vì bạn không lưu) nên khi truy cập nó sẽ crash.

Bạn cần lưu là lưu dữ liệu nằm trong vùng nhớ mà 2 con trỏ đang trỏ tới.

3 Likes

Vòng đời của đối tượng: Bạn truyền tham trị tức là đối tượng mới sẽ được tạo ra (trên stack) theo cách copy. Do sử dụng copy mặc định nên chỉ có copy head với tail :smiley: sau khi rời hàm thì hàm hủy được kích hoạt dỡ hết danh sách bên dưới.
Quay lại bản gốc thì danh sách bên dưới không còn vì hai con trỏ như nhau => truy cập vào thì toạch.

Thực ra copy constructor, copy operator, destructor, move constructor và move assignment operator không thể tách rời. (Rule of five)

4 Likes

cảm ơn mọi người ạ, nhờ mọi người mình hiểu ra nhiều rồi :)))))

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?