Error: Segmentation fault

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 1664 Views - Last Post: 23 November 2012 - 02:06 AM Rate Topic: -----

#1 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Error: Segmentation fault

Posted 20 November 2012 - 05:47 PM

My program is displaying segmentation fault error but still outputs files with containing right datas.
Someone please point out the reason why.

header file:
#include "book.h"
#define BOOK_ENTRIES 10001
#define REQUEST_ENTRIES 501

////////////////////////////////////////////////////////////////////////////////
//-----------------------------Member Functions-------------------------------//
////////////////////////////////////////////////////////////////////////////////

//returns bookinfo private member authorlname
string bookinfo::getlastname()
{
  return authorlname;
}

//returns bookinfo private member authorfname
string bookinfo::getfirstname()
{
  return authorfname;
}

//returns bookinfo private member catalognumber
string bookinfo::getcatnumber()
{
  return catalognumber;
}

//returns bookinfo private member booktitle
string bookinfo::getbooktitle()
{
  return booktitle;
}

//returns bookinfo private member bookgenre
string bookinfo::getgenre()
{
  return bookgenre;
}

//returns bookinfo private member bookavailability
string bookinfo::getavailability()
{
  return bookavailability;
}

/*******************************************************************************
***********************Book Initializing Function*******************************
*******************************************************************************/

/* bookinfo::newbook(string number, string lastname,    initializes a book's
                     string firstname, string title,    catalog number, author's
                     string genre, string availability) last name and first
                                                        name, title, and status
                                                        of availability
   @param number        [in]      The catalog number from input file
   @param lastname      [in]      The last name from input file
   @param first name    [in]      The first name from input file
   @param title         [in]      The title from input file
   @param genre         [in]      The genre from input file
   @param availability  [in]      The genre from input file
   pre-condtion                   Input file is available
   post-condition                 none
   @return                        none
*/

 void bookinfo::newbook(string number, string lastname,
             string firstname, string title, string genre,
             string availability)
{
  catalognumber = number;
  authorlname = lastname;
  authorfname = firstname;
  booktitle = title;
  bookgenre = genre;
  bookavailability = availability;
}


////////////////////////////////////////////////////////////////////////////////
//-----------------------------Non-member Functions---------------------------//
////////////////////////////////////////////////////////////////////////////////

/*******************************************************************************
*****************************Author Sort Function*******************************
*******************************************************************************/

/* authorsort(bookinfo A[], int N) takes an arrray and sorts the array by
                                   last name and first name of the author
   @param A[] [in]                 the array to be analyzed
   @param N   [in]                 the size of the array
   @pre-condition                  The array containing book infomartion
                                   has been initialized
   @post-condition                 none
   @return                         none
*/


void authorsort(bookinfo A[], int N)
{
    int smallest; 
    int first;   

    bookinfo temp[BOOK_ENTRIES];

    for (first = 0; first < N-1; first++) {
        
        smallest = first;
        for (int k = first+1; k <= N-1; k++) {
            //if two authors have the same last names, then the first names
            //of the two authors are compared.
            if ( A[k].getlastname() == A[smallest].getlastname() )
            {
              if ( A[k].getfirstname() < A[smallest].getfirstname() )
                smallest = k;

              else
                smallest = smallest;
            }
            else if ( A[k].getlastname() < A[smallest].getlastname() )
                smallest = k;

        }
        
        //temp[1] is a place holder for the value of A[smallest]
        temp[1] = A[smallest];
        A[smallest] = A[first];
        A[first] = temp[1];

    }

}

/*******************************************************************************
*****************************Genre Sort Function********************************
*******************************************************************************/

/* genresort(bookinfo A[], int N) takes an arrray and sorts the array by
                                   genre and last name of the author
   @param A[] [in]                 the array to be analyzed
   @param N   [in]                 the size of the array
   @pre-condition                  The array containing book infomartion
                                   has been initialized
   @post-condition                 none
   @return                         none
*/

void genresort(bookinfo A[], int N)
{
    int smallest; 
    int first;    

    bookinfo temp[BOOK_ENTRIES];

    for (first = 0; first < N-1; first++) {
        
        smallest = first;
        for (int k = first+1; k <= N-1; k++) {
            //if the genre of two books are the same, then the books are sorted
            //base on last name of the author
            if ( A[k].getgenre() == A[smallest].getgenre() )
            {
              if ( A[k].getlastname() < A[smallest].getlastname() )
                smallest = k;

              else
                smallest = smallest;
            }
            else if ( A[k].getgenre() < A[smallest].getgenre() )
                smallest = k; 

        }

        //temp[1] is a place holder for the value of A[smallest]
        temp[1] = A[smallest];
        A[smallest] = A[first];
        A[first] = temp[1];

    }

}



header file:
#ifndef __book_h__
#define __book_h__

#include <string>


using namespace std;

class bookinfo
{
  public:
  void newbook(string number, string lastname,    //initializes a book info
             string firstname, string title, 
             string genre, string availability);
  string getlastname();     //returns authorlname
  string getfirstname();    //returns authorfname
  string getcatnumber();    //returns catalognumber
  string getbooktitle();    //returns booktitle
  string getgenre();        //returns bookgenre
  string getavailability(); //returns bookavailability
  private:
  string catalognumber;
  string authorlname;
  string authorfname;
  string booktitle;
  string bookgenre;
  string bookavailability;
};


void authorsort(bookinfo A[], int N);

void genresort(bookinfo A[], int N);
#endif




main program:
#include "book.h"
#include <fstream>
#include <iostream>
#include <cstdlib>

using namespace std;

#define BOOK_ENTRIES 10001
#define REQUEST_ENTRIES 501

////////////////////////////////////////////////////////////////////////////////
//-----------------------------------Main-------------------------------------//
////////////////////////////////////////////////////////////////////////////////

int main ( int argc, char * argv[] )
{
    ifstream libfin;     //input file stream for library holdings
    ifstream reqfin;     //input file stream for list of book request
    ofstream authorfout; //output file stream for author sort
    ofstream genrefout;  //output file stream for genre sort
    ofstream checkfout;  //output file stream for checkout
    
    if ( argc < 6 )
    {
      cout << "Not enough files to program" << endl;
      exit(1);
    }
    libfin.open( argv[1] );
    if ( libfin.fail() ) {
        cerr << "Could not open studentdata for reading.\n";
        exit(1);
        }
              
    reqfin.open( argv[2] );
    if ( reqfin.fail() ) {
        cerr << "Could not open studentdata for reading.\n";
        exit(1);
        }

    authorfout.open( argv[3] );
    genrefout.open( argv[4] );
    checkfout.open( argv[5] );
    
    bookinfo booklist[BOOK_ENTRIES];     //declaring an array of type bookinfo
    string bookrequest[REQUEST_ENTRIES]; //declaring an array of type string
    
    string number;
    string lname;
    string fname;
    string title;
    string genre;
    string availability;
    
    int i = 0;
    while ( i < BOOK_ENTRIES && !libfin.eof() )
    {
       //getline is being use since there are six tokens
       //separated by tabs. The character deliminator of getline
       //proved to be very useful.
       getline(libfin, number, '\t');
       getline(libfin, lname, '\t');
       getline(libfin, fname, '\t');
       getline(libfin, title, '\t');
       getline(libfin, genre, '\t');
       getline(libfin, availability, '\n');
      //calls the newbook member function of bookinfo for initialization
      booklist[i].newbook(number, lname,fname,title,
              genre, availability);
      i++;
     }
     
     int k = 0;
     while ( k < REQUEST_ENTRIES && !reqfin.eof() )
     {
       getline(reqfin, bookrequest[k]);
       k++;
     }
     
////////////////////////////////////////////////////////////////////////////////
//------------------------------Author Sort-----------------------------------//
////////////////////////////////////////////////////////////////////////////////

     //calls authorsort function before authorfout so that the data
     //will be sorted base on last name and first name of the book's
     //author
     authorsort(booklist, i);
     int m = 0;
     while ( m < i )
     {
       authorfout << booklist[m].getcatnumber() << '\t'
           << booklist[m].getlastname() << '\t'
           << booklist[m].getfirstname() << '\t'
           << booklist[m].getbooktitle() << '\t'
           << booklist[m].getgenre() << '\t'
           << booklist[m].getavailability() << endl;
       m++;
     }

////////////////////////////////////////////////////////////////////////////////
//------------------------------Genre Sort------------------------------------//
////////////////////////////////////////////////////////////////////////////////

     //calls genresort function before genrefout so that the data
     //will be sorted base on genre and last name of the author
     genresort(booklist, i);
     int j = 0;
     int n = 0;
     while ( j < i )
     {
        //if the next genre is different from the current, then the current
        //genre will be send to output file stream so that it will look
        //like this:
        // Genre
        // book1
        // boook2
        // book3
        //
        // Genre2
        // book1
        // book2
        // book3
        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )
         {
           genrefout << booklist[n].getgenre() << endl;
         }
          genrefout << booklist[j].getcatnumber() << '\t'
           << booklist[j].getlastname() << '\t'
           << booklist[j].getfirstname() << '\t'
           << booklist[j].getbooktitle() << '\t'
           << booklist[j].getgenre() << '\t'
           << booklist[j].getavailability() << endl;
           
        //if the next genre is different, then n will be equals to the value
        //of j + 1 so that the next genre will be sent to output file stream
        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )
           {
             n = j+1;
           }
           j++;
           genrefout << endl;
     }

////////////////////////////////////////////////////////////////////////////////
//-----------------------------------Check Out--------------------------------//
////////////////////////////////////////////////////////////////////////////////
     int p = 0;
     int q = 0;
     while ( q < k )
     {
       //if the catalog number from the book request list matches that of the
       //catalog number of a book from the book list, then the book's
       //catalog number, book title and status of availability are sent
       //to the output file stream
       if ( bookrequest[q] == booklist[p].getcatnumber() )
       {
         checkfout << booklist[p].getcatnumber() << '\t'
                   << booklist[p].getbooktitle() << '\t'
                   << booklist[p].getavailability() << endl;
         p = 0; //resets p to 0
         q++;   //moves to the next catalog number in the book request list
       }
       
       else
         p++; //increments to the next book to find a match
       
       //if p reaches the value of i, then that means the catalog number in 
       //the book request list doesn't match any of the catalog number in the 
       //book list. The catalog number and the status of "unavailable" are sent
       //to the output file stream
       if ( p == i )
       {
         checkfout << bookrequest[q] << '\t'
                   << "unavailable" << endl;
         q++;
       }
        
     }

////////////////////////////////////////////////////////////////////////////////
//------------------------------------End-------------------------------------//
////////////////////////////////////////////////////////////////////////////////
     checkfout.close();
     genrefout.close();
     libfin.close();
     reqfin.close();
     authorfout.close();
     
     return 0;
}



Is This A Good Question/Topic? 0
  • +

Replies To: Error: Segmentation fault

#2 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1431
  • View blog
  • Posts: 4,963
  • Joined: 19-February 09

Re: Error: Segmentation fault

Posted 20 November 2012 - 06:14 PM

Here j+1 can equal i which is BOOK_ENTRIES and so the value is outside of valid range :

108	     while ( j < i )
109	     {
     // ...
122	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )
     // ...
135	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )




It might be clearer to use BOOK_ENTRIES instead of i in some cases.


Do you really need an array of temp bookinfo's here?

102	    bookinfo temp[BOOK_ENTRIES];


Was This Post Helpful? 1
  • +
  • -

#3 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 20 November 2012 - 07:04 PM

View Post#define, on 20 November 2012 - 06:14 PM, said:

Here j+1 can equal i which is BOOK_ENTRIES and so the value is outside of valid range :

108	     while ( j < i )
109	     {
     // ...
122	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )
     // ...
135	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )




It might be clearer to use BOOK_ENTRIES instead of i in some cases.


Do you really need an array of temp bookinfo's here?

102	    bookinfo temp[BOOK_ENTRIES];



Thank you for pointing out the error. A question though, why does my program still outputs files even though it causes segmentation fault?
Was This Post Helpful? 0
  • +
  • -

#4 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Error: Segmentation fault

Posted 20 November 2012 - 07:20 PM

using namespace std;

You shouldn't put that in global scope in your header files. It can possibly bring you subtle name-resolving related bugs.

A set of files needed to test the output would be beneficial. (to see where it segfaults)


Just from looking at the code:
//main.cpp:73
while ( k < REQUEST_ENTRIES && !reqfin.eof() )
You check if EOF was reached before actually extracting data that would then set EOF bit in the streams error state. You want to use the object itself to check the state rather than .eof().
In simple cases:
while (std::getline(stream, line)) { }
while (stream >> value) { }
Notice that in both cases the error state is checked after extraction. If you don't see where - see ios::operator void*.
You can either make your case a simple case (get a line first, then process the line using stringstream and getline, preferably in a loop, so it would shorten the code), or make it more complicated. I don't like "complicated" that much.

You have no constructor for bookinfo class, so default constructor has been synthesized for you. However, you have a ::newbook() member function that looks like a constructor much. Why not make it one? You would have to provide a no-parameter one too, so you could still be able to use static arrays of instances, but that's not a problem. Well, to get the rest of the code unchanged you'd also probably have to overload operator=, but seeing as you already have it almost ready...
Still, that's not an immediate problem.

Lines 90, 126 - you could overload operator<<, or make a member function to provide such an info in a string, or sent it to input stream.

#define __book_h__
Be careful here, identifiers with double underscores (like you used) and those that start with underscore and uppercase letter (_Whatever) are restricted for any use, AFAIK in any scope. Also in global scope identifiers starting with underscore are restricted for implementation. (you can still have member or local variables named like _member).


Actually, that whole array business is ugly and unwieldy. Why not just use a std::vector, or any other container?

This post has been edited by Xupicor: 20 November 2012 - 07:22 PM

Was This Post Helpful? 1
  • +
  • -

#5 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 20 November 2012 - 07:26 PM

I am not able to use other containers because I haven't learned vectors yet.
Was This Post Helpful? 0
  • +
  • -

#6 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 249
  • View blog
  • Posts: 582
  • Joined: 31-May 11

Re: Error: Segmentation fault

Posted 20 November 2012 - 07:29 PM

Can you post the test files you use?

edit: Sorry, it got late here. I'll get back to the topic tomorrow morning. ;) Nighty!

This post has been edited by Xupicor: 20 November 2012 - 07:35 PM

Was This Post Helpful? 0
  • +
  • -

#7 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 20 November 2012 - 07:42 PM

I changed the getline part to this and still getting a crash:
int i = 0;
	getline(libfin, number, '\t');
       getline(libfin, lname, '\t');
       getline(libfin, fname, '\t');
       getline(libfin, title, '\t');
       getline(libfin, genre, '\t');
       getline(libfin, availability, '\n');
    while (!libfin.eof() )
    {
       //getline is being use since there are six tokens
       //separated by tabs. The character deliminator of getline
       //proved to be very useful.
	   	booklist[i].newbook(number, lname,fname,title,
              genre, availability);
	    i++;
       getline(libfin, number, '\t');
       getline(libfin, lname, '\t');
       getline(libfin, fname, '\t');
       getline(libfin, title, '\t');
       getline(libfin, genre, '\t');
       getline(libfin, availability, '\n');
      
     }


Was This Post Helpful? 0
  • +
  • -

#8 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 20 November 2012 - 08:23 PM

I also removed all the j+1 and still no good.
Was This Post Helpful? 0
  • +
  • -

#9 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 20 November 2012 - 08:30 PM

View Post#define, on 20 November 2012 - 06:14 PM, said:

Here j+1 can equal i which is BOOK_ENTRIES and so the value is outside of valid range :

108	     while ( j < i )
109	     {
     // ...
122	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )
     // ...
135	        if ( booklist[j].getgenre() != booklist[j+1].getgenre() )




It might be clearer to use BOOK_ENTRIES instead of i in some cases.


Do you really need an array of temp bookinfo's here?

102	    bookinfo temp[BOOK_ENTRIES];




I removed the j+1 part and the program still crashes
Was This Post Helpful? 0
  • +
  • -

#10 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,433
  • Joined: 25-December 09

Re: Error: Segmentation fault

Posted 20 November 2012 - 10:33 PM

My first question is do you actually need an array of 10001 bookentries? If you do then I suggest you dynamically allocate this array.

Jim
Was This Post Helpful? 0
  • +
  • -

#11 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 21 November 2012 - 06:36 PM

View Postjimblumberg, on 20 November 2012 - 10:33 PM, said:

My first question is do you actually need an array of 10001 bookentries? If you do then I suggest you dynamically allocate this array.

Jim


Yes I do. There are at most 1000 bookentries.
Was This Post Helpful? 0
  • +
  • -

#12 jimblumberg  Icon User is online

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,433
  • Joined: 25-December 09

Re: Error: Segmentation fault

Posted 21 November 2012 - 06:56 PM

Quote

Yes I do. There are at most 1000 bookentries.

If you can have at most 1000 bookentries why are you trying to declare 10,001 of them.
#define BOOK_ENTRIES 10001
int main ( int argc, char * argv[] )
{
...
    bookinfo booklist[BOOK_ENTRIES];     //declaring an array of type bookinfo
    string bookrequest[REQUEST_ENTRIES]; //declaring an array of type string



If you do need ten thousand you will probably need to dynamically allocate this amount so you don't run out of stack memory.

Jim
Was This Post Helpful? 0
  • +
  • -

#13 zethulon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 25-September 12

Re: Error: Segmentation fault

Posted 21 November 2012 - 08:36 PM

View Postjimblumberg, on 21 November 2012 - 06:56 PM, said:

Quote

Yes I do. There are at most 1000 bookentries.

If you can have at most 1000 bookentries why are you trying to declare 10,001 of them.
#define BOOK_ENTRIES 10001
int main ( int argc, char * argv[] )
{
...
    bookinfo booklist[BOOK_ENTRIES];     //declaring an array of type bookinfo
    string bookrequest[REQUEST_ENTRIES]; //declaring an array of type string



If you do need ten thousand you will probably need to dynamically allocate this amount so you don't run out of stack memory.

Jim


I still don't get why there would be a segmentation fault. Can you please explain why?
Was This Post Helpful? 0
  • +
  • -

#14 raghav.naganathan  Icon User is offline

  • Perfectly Squared ;)
  • member icon

Reputation: 408
  • View blog
  • Posts: 1,440
  • Joined: 14-September 12

Re: Error: Segmentation fault

Posted 21 November 2012 - 09:20 PM

View Postzethulon, on 22 November 2012 - 09:06 AM, said:

I still don't get why there would be a segmentation fault. Can you please explain why?


Well, if you want more information on why this occurs, I would suggest you go through Reasons for segmentation fault

regards,
Raghav
Was This Post Helpful? 0
  • +
  • -

#15 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Error: Segmentation fault

Posted 21 November 2012 - 09:52 PM

You are declaring your array inside a function - that means memory for it, will be allocated from a small memory block set aside for it, called the "stack". As indicated by Jim, above, stack size is small (much smaller than the heap area), and so you are running out of space. That will always cause a seg fault, barring some way to handle that error before it becomes critical.

So, your possible answers are one of these:

1) dynamically allocate memory for the array, from the heap block of memory, which can be done inside any function. (and don't forget to free it when it's no longer needed).

or

2) move your array creation line of code to space above main() - and make it global. Global arrays are given memory from the heap, automatically. All functions will be able to work with and change data in a global array.

If you make this change, and STILL have a segmentation fault at run-time, then you are having yet another problem - a memory problem can be fixed, and other problems may still persist, but at last you'll know memory is not the problem - the heap can use all the available memory.

This post has been edited by Adak: 21 November 2012 - 09:53 PM

Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2