Segment fault khi đọc danh sách liên kết từ file

xin chào tất cả mọi người ! cho em hỏi là hàm nhap_list2 sao lại bị segment fault ? và giải quyết như thế nào ạ? Em cảm ơn!l

//danh sách liên kết các số nguyên
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

struct node//1 khai báo node
{
    int data;
    node *next;
};

struct list//2 khai báo list là danh sách liên kết chứa các node
{
  node *head;  
};

node* tao_node()//3 khởi tạo node
{
    node*p=new node;
    cout<<"nhap gia tri cho node : "; cin>>p->data;
    p->next=NULL;
    return p;
}

void tao_list(list &l)//4 khởi tạo list
{
  l.head=NULL;
}

void them_dau(list &l)//5 thêm đầu
{
  node*p=new node;
  p=tao_node();
  if(l.head==NULL) l.head=p;
  else
  {
    p->next=l.head;
    l.head=p;
  }
}

void them_cuoi(list &l)// 6 thêm cuối
{
  node*p=new node;
  p=tao_node();
  if (l.head==NULL) l.head=p;
  else
  {
    node*q=l.head;
    while (q->next!=NULL)
    {
      q=q->next;
    }
    q->next=p;
  }
}

void duyet_list(list l)//7 duyệt list
{
  node * q= l.head;
  while(q->next!=NULL) q=q->next; 
}

void nhap_list1(list &l)//8.1 nhập list từ bàn phím
{
  node*q=l.head;
  while(q!=NULL)
  {
    cin>>q->data;
    q=q->next;
  }
}

void nhap_list2(list &l)//8.2 nhập list từ file
{
  string filename;
  cout<<"nhap ten file : "; cin.ignore(); getline(cin, filename);
  fstream file (filename, ios::in|ios::binary);
  node*q=l.head;
  while(file)
  {
    file.read(reinterpret_cast<char*>(&(q->data)), sizeof(int));
    q=q->next;
  }
  file.close();
}

void xuat_list1 (list l)//9.1 xuất list ra màn hình
{
  node*q=l.head;
  while(q!=NULL)
  {
    cout<<q->data<<' ';
    q=q->next;
  }
  cout<<endl;
}

void xuat_list2 (list l)//9.2 xuất list ghi vào file
{
  string filenames;
  cout<<"nhap ten file : "; getline(cin, filenames);
  fstream file (filenames, ios::out|ios::binary);
  node*q=l.head;
  while (q!=NULL)
  {
    file.write(reinterpret_cast<char *>(&(q->data)), sizeof(int));
    q=q->next;
  }
  file.close();
}

int chieu_dai_list(list l)//10 chiều dài list
{
  node*q=l.head;
  int chieudai=0;
  while (q!=NULL)
  {
    chieudai++;
    q=q->next;
  }
  return chieudai;
}

int tim_kiem(list l, int x)//11 tìm kiếm vị trí của node có data = x trong list
{
  node*q=l.head; int vitri=1;
  while(q!=NULL)
  {
    if (q->data==x) return vitri;
    q=q->next;
    vitri++;
  }
  return 0;// ngầm định vị trí 0 tương đương không tìm thấy trong danh sách liên kết, vì danh sách liên kết bắt đầu từ 1, khác với mảng bắt đầu từ 0
}

void hoanvi (int &x,int &y)
{
    int t=x; x=y; y=t;
}

void max_data (list l)//12 ghi vào file danh sách các phần tử có giá trị lớn nhất
{
  string filename;
  cout<<"nhap ten file : "; cin.ignore(); getline(cin,filename);
  fstream file(filename, ios::out|ios::binary);
  int max=l.head->data;
  node*q;
  for ( q=l.head;q!=NULL;q=q->next)
  {
    if(q->data>max) max=q->data;
  }
  for (q=l.head;q!=NULL;q=q->next)
  {
    if (q->data==max)
    {
      file.write(reinterpret_cast<char*>(&(q->data)),sizeof(int));
    }
  }
  file.close();
}

void sapxep(list l)//13 sắp xếp tăng dần
{
  node*q; node*r;
  for (q=l.head;q!=NULL;q=q->next)
  {
    for(r=q->next;r!=NULL;r=r->next)
    {
      if (q->data>r->data) hoanvi(q->data,r->data);
    }
  }
}

void them_bat_ki (list &l, int k)// 14 thêm node vào vị trí bất kì
{
  node *p=new node; int vitri=1;
  p=tao_node();
  if (l.head==NULL||k==1) l.head=p;
  else
  {
    if (k>chieu_dai_list(l)) them_cuoi(l);
    else
    { 
      node*q=l.head; node *r;
      while(vitri!=k-1)
      {
        vitri++;
        q=q->next;
        r=q->next;
      }
      p->next=r;
      q->next=p;
    }
  }
}

void xoa_dau(list &l)//15.1 xóa node đầu
{

}

void xoa_cuoi(list &l)//15.2 xóa node cuối
{

}

void xoa_bat_ki(list &l,int k)//15.3 xóa node ở vị trí thứ k
{

}

void xoa_node_x(list &l, int x)//15.4 xóa node có giá trị x
{

}

void xoa_list(list &l)//15.5 xóa danh sách
{
  l.head=NULL;
}

int main()
{
  list l;
  tao_list(l);
  cout<<"them 1 node vao dau danh sach : "<<endl; them_dau(l);
  cout<<"them 1 node vao dau danh sach : "<<endl; them_dau(l);
  cout<<"them 1 node vao dau danh sach : "<<endl; them_dau(l);
  cout<<"them 1 node vao vi tri thu 3 trong danh sach list : "<<endl; them_bat_ki(l,3);
  cout<<"them 1 node vao cuoi danh sach : "<<endl; them_cuoi(l);
  cout<<"xuat list : "; xuat_list1 (l);
  cout<<"chieu dai list : "<<chieu_dai_list(l)<<endl;
  cout<<"vi tri cua node co data = 5 trong list : "<<tim_kiem(l,5)<<endl;
  sapxep(l);
  cout<<"list sau khi sap xep tang dan : "; xuat_list1 (l);
  max_data(l);
  xuat_list2(l);
  nhap_list1(l);
  nhap_list2(l);
  xuat_list1(l);

  system("pause");
  return 0;
}

Mình thấy những hàm khác đó có kiểm tra q->next != NULL hoặc q != NULL, nhưng hàm này bạn lại không kiểm tra q->next hay q gì cả?
Lý do gì khiến bạn làm vậy?

Mà nhập vào DSLK thì sai mất rồi, nhập mới chứ có phải nhập từ cái có sẵn đâu mà làm vậy.

2 Likes

Em cảm ơn, em sẽ xem lại ạ

Thường SEGFAULT xuất hiện khi access vào con trỏ nhưng con trỏ đấy đang NULL

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