Segmentation fault error

I am trying to write a code that reads data from a file, after reading the data it should look for duplicate and write only non duplicate values to a new file. however, when I run the program I get a segmentation error inside GetNext(). I've gone through the code several times I can't seem to find the invalid pointer inside GetNext() function. can any body help! see the code bellow.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//===========================================================================
// hybrid.h -- Specification file for hybrid class
// Time-stamp: <2010-10-25 19:24:46 Dnambembe>
// To compile:
//   
// Copyright (c) 2010 by Domingos Nambembe. All rights reserved.
//===========================================================================
#include<fstream>

#define OUTDATA  "licence.txt" // reading from file
#define fn "Noduplicate.text" //sorted file


struct NodeType;        //Forward declaretion, complete declaretion is hiden

struct Record; 

typedef Record ComponentType;                      // in implementation file

class HybridList
{
public:
   
   void GetNext();   // extracts record from a file Licensea
   void ReStart();   // calls getnext to get data
   void SaveDB(Record* K); //create file with no duplicate
   bool IsEmpty() const;
             //condition:
             // function value == true. if list is empty
             //                == false, otherwise

   void Insert();
          //  precondition item is not in the list
         //postcondition: item inserted && list is in ascending order


   void Delete( ComponentType item);
        // precondition: item is somewhere in list
        //postcondition: item deleted && list in ascending order

   HybridList();
      // default constractor
      // empty list is created

   //HybridList(const SortedList& otherlist);
       // copy-constractor, list is created as duplicate

   ~HybridList();
     // destructor
     // list is destroyed 
private:
   NodeType* head;
   //Record Data;
};




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

// hybrid.cpp --this file implement the hybridlist class  
// Time-stamp: <2010-10-29 18:52:46 Dnambembe>
// To compile:
//   g++  hybrid.cpp
// Copyright (c) 2010 by Domingos Nambembe. All rights reserved.
//===========================================================================

#include<iostream>
#include<cstddef>  //need NULL
#include"hybrid.h"


using namespace std;

typedef NodeType* NodePtr;  //node pointer for hybrid class
typedef Record* PTR;     // node pointer for data struct
 
struct Record
{
  char NameAddress[128];
  long int LicenseN;
  PTR  Link1;
}Mydata;

struct NodeType
{
 ComponentType component;
 NodePtr   Link;
};

Record Data; //global data
// method that construct an empty list

HybridList::HybridList()
// constructor
// postcondition: head == NULL
{
   head == NULL;
}


// a method that test for empty list

bool HybridList::IsEmpty() const
{
 
 return (head == NULL); // return true if head == NULL.
}


 
// inserting item function
void HybridList::Insert( )
{
 // precondition: component members of the list are in ascending order
 //postcondition: new Node containing item is in proper place
 
 NodePtr newNodePtr = new NodeType; // set-up node to be inserted
 newNodePtr->component = Data;
 
 NodePtr prevPtr = NULL;
 NodePtr currentPtr = head;
 while(currentPtr != NULL && Data.LicenseN > currentPtr->component.LicenseN)
  {
   prevPtr = currentPtr;
   currentPtr = currentPtr->Link; // searching for proper place for item
  }
   
  if(prevPtr->component.LicenseN == newNodePtr->component.LicenseN)return;
    // if license number are iqual exit
 // insert item
  ComponentType newData = Data; //pass the struct record
  SaveDB(&newData); //write the sorted data to new file
 newNodePtr->Link = currentPtr;
 if(prevPtr == NULL) head = newNodePtr;
 
  else
  
  prevPtr->Link = newNodePtr;

  
 delete newNodePtr;
}
 

// class destructor for 

HybridList::~HybridList()
{
 
  //ComponentType temp;  // temporary variable
  
 // while(!IsEmpty()) RemoveFirst(temp);
 }


// implementation for GetNext() function

void HybridList::GetNext()
{
    ifstream bofs(OUTDATA, ios::in | ios::binary | ios::ate);
  //bofs.seekg(0, ios::beg);
    if(!bofs) cout<< "Unable to open file"<<endl;

  bofs.read((char*)&Mydata, sizeof(Data));
  Data = Mydata;
  cout<< Mydata.NameAddress<<endl;
  cout<<Mydata.LicenseN<<endl;
  bofs.close();
}

// Restart

void HybridList::ReStart()
{
 GetNext();
}
 

  
// writing new file
void HybridList::SaveDB(Record *rec)
{
  
  ofstream ofs(fn, ios::binary | ios::app);
  if(!ofs) cout<<"error";
  ofs.write((const char*) rec, sizeof(Record));
  ofs.close();
}
  




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//===========================================================================
// testhybrid.cpp --a test driver for  the hybridlist class  
// Time-stamp: <2010-10-29 18:52:46 Dnambembe>
// To compile:
//   g++ testhybrid.cpp  hybrid.o
// Copyright (c) 2010 by Domingos Nambembe. All rights reserved.
//===========================================================================

#include"hybrid.h"
#include<iostream>

using namespace std;

int main()
{
 HybridList object;
 for(int i = 0; i < 3; i++)
  {
  // object.ReStart();
   object.GetNext();
   object.Insert();
   cout<< " Licensea file has been sorted and written to new file" <<endl;
   }
}
It seems to me this is probably the most error-prone line in that member function:
 
bofs.read((char*)&Mydata, sizeof(Data));




is the size of the two records always the same? Check to make sure this doesn't over-write your pointer to a new element. That will cause a seg-fault. Also, this may be more a matter of preference, but perhaps when doing something of this nature you should use the size of the class/struct type (or data member!) instead of an instance of it.

Also, just purely for your benefit, I would like to know if you can use your IDE's debugging features--Visual Studio has excellent debugging features.

Hope it helps.
Last edited on
Hi
please show the lincence.txt.
it look like the input file has problem.
hi aiby
I don't think the input file has a problem. the licence.txt is a file I created using the code below if you compile and run it you have the
file created in your directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 //===========================================================================
// builtdoc.cpp -- The implementation file for the classes that create 
// Time-stamp: <2010-10-19 20:39:46 Dnambembe>
// To compile:
//   g++ -c builtdoc.cpp
// Copyright (c) 2010 by Domingos Nambembe. All rights reserved.
//===========================================================================

#include "builtdoc.h"

typedef Record* NodePtr;


struct Record
{
  char Rcomponent[128];
  
  long int Dlicense;
  
  NodePtr Link;

};




 NodePtr currentPtr;
 NodePtr head;
//string Num;

// implementing the constructor
Tbuiltdoc::Tbuiltdoc()
{
   head == NULL;
 }

// Destructor
Tbuiltdoc::~Tbuiltdoc()
{
  cout<< "Inside the distructor for "<< /*NameAddress*/1 << endl;
  cout<< " Press enter to quit" <<endl;
  cin.get();
  
 // delete[] NameAddress;   // Delete dynamic memory
  
} 
int first = 1; 
// to insert first recor
void Tbuiltdoc::SaveDB(Record *rec)
{
   // NodePtr newNodePtr = new Record; // set-up node to be inserted
   NodePtr newNodePtr = rec;
   //rec = currentPtr;
  ofstream ofs(fn, ios::binary | ios::app);
  if(!ofs) cout<<"error";
  ofs.write((const char*) rec, sizeof(Record));
  ofs.close();
  if(IsEmpty()){ head = newNodePtr; //if first record
  currentPtr = head;}
  else {
  currentPtr->Link = newNodePtr;
  currentPtr = currentPtr->Link;}
}

// isempty function

bool Tbuiltdoc::IsEmpty()
{
 return(head == NULL); // if no record is created, call "InsertFirst" 
} 




void Tbuiltdoc::GetInput()
{
   Record reco;
    //prompt user to create database
  for( int i = 0; i < 3; i++)
  {
   
   cout<< "Enter name and address" <<endl;
     int buf_size = 128;
     cin.get(reco.Rcomponent, buf_size); 
   

   cout<<"Enter Driver's Licence Number " <<endl;
      cin >> reco.Dlicense;
      cin.ignore();
    

   SaveDB(&reco); cout<<"Data saved"<<endl;
   
   //else
    // cout<< "Unable to save database"<<endl;
   
   }

}         



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//============================================================================
// builtdoc.h -- A declaration for the classes that create the record of driv
// Time-stamp: <2010-10-19 19:51:46 Dnambembe>
// 
//   
// Copyright (c) 2010 by Domingos Nambembe. All rights reserved.
//============================================================================

#ifndef __builtdoc_H
#define __builtdoc_H   // Prevent multiple #includes

#include<iostream>
#include<string.h>  // need strlen & strcopy
#include<string>
#include<fstream>

#define fn "licence.txt"

using namespace std;

struct Record ;    // forward declaration

class Tbuiltdoc
{
 
 public:
  Tbuiltdoc(); // prompt user to enter name & address first
                              //then License number
  ~Tbuiltdoc();
  bool IsEmpty(); //call first to see if first record is not created
  void SaveDB(Record *af); // this will insert subsiquent records
  void GetInput();
 private:
  // char* NameAddress;   // the string containg name and address

   //long int License;    // License number string
    // pointer to the record struct
 
};

#endif  // __bstream_H
Hi dnambembe
you should check the code in Inser() as below:
if(prevPtr->component.LicenseN == newNodePtr->component.LicenseN)return;

I has debug on my Dev-cpp and it is says "Segmentation Fault"

I'm busy now but I will be keep look this tip to help you
I found the bug here you are:

void HybridList::Insert( )
{
// precondition: component members of the list are in ascending order
//postcondition: new Node containing item is in proper place

NodePtr newNodePtr = new NodeType; // set-up node to be inserted
newNodePtr->component = Data;

NodePtr prevPtr = NULL;
NodePtr currentPtr = head;
while(currentPtr != NULL && Data.LicenseN > currentPtr->component.LicenseN)
{
prevPtr = currentPtr;
currentPtr = currentPtr->Link; // searching for proper place for item
if((prevPtr->component.LicenseN) == (newNodePtr->component.LicenseN))return;
}


// if license number are iqual exit
// insert item
ComponentType newData = Data; //pass the struct record
SaveDB(&newData); //write the sorted data to new file
newNodePtr->Link = currentPtr;
if(prevPtr == NULL) head = newNodePtr;

else

prevPtr->Link = newNodePtr;


delete newNodePtr;
}
thanks aiby,

that was the problem.

I have a question
what type of debugger you use ?

I use gdb and it did not allow me to trace the bug
Hi dnambembe
I used Dev-cpp4.9.9.2 for windows xp.
I'm going to linux to C/C++/QT programming at next week, so did you have any suggest for me such as linux version,tools,etc..
hi aiby

for linux version snd tools, i'll suggest a linux ubuntu 10.4 which is free and it allows you to download any application and tools you might need for your project. however if you are looking for something very fancy the latest mandrake version will be best because I found out that there a lot of books writen specifically for MN.
Hi danmbembe
Thank you very much.I just want a good begging in linux programming.
Topic archived. No new replies allowed.