Solved

Segmentation Fault Error C++

Posted on 2010-09-15
17
727 Views
Last Modified: 2012-05-10
Tried compiling the following code in g++ (Linux), and it does compile correctly without a problem.
However when I execute
It runs correctly for the first 50-100 csv file rows but then before the fourth variable is set to be entered, it issues segmentation fault!
This program worked all right in Windows XP in DOS.
an anybody tell me the reason of the error and tell me what extra code /pointer or syntax I have to change. If you can give me an example that would be good. Feel free to edit the code. I’m new to C++.
note (i found the code on the internet) i only made some changes in void csv::write(). so the problem might be in void csv::write() - the problem might be how i define  std::stringstream message_data;

thanks

#ifndef CSV_H

#define CSV_H



#include <iomanip>

using std::endl;



#include <sstream>

using std::stringstream;;

#include <fstream>

using std::ifstream;

using std::ofstream;



#include <string>

using std::string;



#include <vector>

using std::vector;



class csv

{

      friend bool operator==( const csv &, const csv & );

      friend bool operator!=( const csv &, const csv & );



      public:

            csv();

            csv(const char* );

            void read( const char* );

            void write();

            string getfield( int, int );

            void setfield( int, int, string );

            const csv &operator=( const csv & );

            int rows, cols;



      private:

            vector < vector <string> > data;

};



csv::csv()

{

      rows = cols = 0;

     // data.push_back( vector <string>() );

}



csv::csv( const char* fname )

{

      read( fname );

}



const csv &csv::operator=( const csv &n )

{

      rows = n.rows;

      cols = n.cols;

      data = n.data;



      return *this;

}



void csv::read(const char* fname )

{

      ifstream in( fname );

      string element, delimiters = ",\n\r";

      char ch;



      rows = cols = 0;

      data.clear();



      data.push_back( vector <string>() );



      while( in.read( (char*)&ch, 1 ) )

      {

            if( delimiters.find_first_of(ch) == delimiters.npos )

                  element += ch;



            else

            {

                  if( ch != '\r' )

                  {

                        data[rows].push_back( element );

                        element = "";

                        if( ch == '\n' )

                        {

                              data.push_back( vector <string>() );

                              rows++;

                        }

                  }

            }

      }



      in.close();

      data[rows].push_back( element );

      cols = data[0].size();

      rows = data.size();

}



void csv::write()

{

      for( int x = 0; x < rows; x++ )

      {

	      std::stringstream message_data;

            for( int y = 0; y < cols; y++ )

            {

		  message_data << data[x][y];

                  if( y != cols - 1 )

	      message_data << ",";

            }

	   message_data << endl;

	   std::cout <<  message_data.str();

      }



     

}



string csv::getfield( int x, int y )

{

      return data[x][y];

}



void csv::setfield( int x, int y, string val )

{

      data[x][y] = val;

}



bool operator==( const csv &d1, const csv &d2 )

{

      return d1 == d2;

}



bool operator!=( const csv &d1, const csv &d2 )

{

      return d1 != d2;

}



#endif



---------------new file-------------------------



#include <iostream>

#include <iomanip>

#include "csv.h"



using namespace std;



int main()

{

      csv mycsv("Book1.csv");

      mycsv.setfield(0,0,"testing");

    mycsv.write();



      return 0;

}

Open in new window

0
Comment
Question by:habte
  • 8
  • 4
  • 3
  • +1
17 Comments
 
LVL 53

Accepted Solution

by:
Infinity08 earned 100 total points
Comment Utility
The cause of the segmentation fault is very likely because the number of fields on each line is not always the same.

The code assumes that each line in the csv file will have the same number of delimiters. That's an assumption you should be careful with.


There are a few more things that are wrong with the code. To name a few :

(a) the operator== and operator!= are defined recursively. You don't want to cal them heh :)

(b) the getfield and setfield methods do not check if the indexes passed as parameter are within the bounds of the vector.

(c) the read method could have been implemented in a nicer way, by making use of the standard STL string functions. But that's not really a problem - just a possible improvement.

(d) the assignment operator does not check for self assignment.
0
 

Author Comment

by:habte
Comment Utility
I’m very new to C++, can you give me code example how to fix the issue
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
In addition to what infinity has mentioned it might help to check the normal causes for a seg fault. In case you haven't read up on it here are a few links

http://www.cprogramming.com/debugging/segfaults.html
http://en.wikipedia.org/wiki/Segmentation_fault
http://web.mit.edu/10.001/Web/Tips/tips_on_segmentation.html

Also it wouldn't hurt to reserve capacity for your vector. See my snippet below
const int NOOFROWS = 1000
const int NOOFSTRINGS = 100 

data.reserve(NOOFROWS)
..
...
data.push_back( vector <string>() );

data[rows].reserve(NOOFSTRINGS)
..
...
data[rows].push_back( element );

Open in new window

0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
I would suggest you put in as many logging statements in your program, log the output to a file. Place the logging statements in important places so that you can study the log files generated.

This will help you understand the flow of the program and also give you an indication of how far the program has progressed when a seg fault occurs
0
 

Author Comment

by:habte
Comment Utility
getting the following errors
csv.h:33: error: ISO C++ forbids initialization of member ‘NOOFROWS’
csv.h:33: error: making ‘NOOFROWS’ static
csv.h:34: error: ISO C++ forbids initialization of member ‘NOOFSTRINGS’

where would you add the variables in the code? can you perhaps update  the code
const int NOOFROWS = 1000
const int NOOFSTRINGS = 100

data.reserve(NOOFROWS)
..
...
data.push_back( vector <string>() );

data[rows].reserve(NOOFSTRINGS)
..
...
data[rows].push_back( element );
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
oops mine was just a snippet.

what have you entered in your header ?
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
i hope u entered semi colons, and removed all those ...
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
you can add the following in your .cpp files
const int NOOFROWS = 1000;

const int NOOFSTRINGS = 100; 



//here goes. see where I have inserted my code



data.clear();

data.reserve(NOOFROWS);

data.push_back( vector <string>() );



while( in.read( (char*)&ch, 1 ) )

      {

        data[rows].reserve(NOOFSTRINGS);

if( delimiters.find_first_of(ch) == delimiters.npos )

                  element += ch;



            else

            {

                  if( ch != '\r' )

                  {

                        data[rows].push_back( element );

                        element = "";

                        if( ch == '\n' )

                        {

                              data.push_back( vector <string>() );

                              rows++;

                        }

                  }

            }

      }

Open in new window

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
I would strongly suggest you add logging statements in your code. Do you know how to do this ?
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 132 total points
Comment Utility
Since you are new to C++, I recommend that you try to find out where the program is crashing. If you are using Visual Studio, then I suggest that you step through its debugger, which only takes 15 minutes to get through the learning curve.

I ran it in the debugger, and found your problem in one minute. I'll be around if you have problems with this approach. And it only takes one added line of code to correct the exception.

Your program is able to handle a variable number of fields per row. After adding the one LOC, it ran on a file with two rows. In one case, both rows had four columns. In another run, the second row had 6 columns.

Here is a link on getting started with Visual Studio 2008 Express Debugger:
    http://www.experts-exchange.com/Programming/Languages/CPP/A_2688-Microsoft-Visual-Studio-2008-Express-C-Quick-and-Dirty-Debugger-Tutorial.html

If that link does not work, then try this one (EE has had some link issues in the last few months):
    http://www.experts-exchange.com/A_2688.html
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 132 total points
Comment Utility
I didn't see all the previous comments about putting in logging messages. Yes, that is another good way to debug if you don't have a debugger. The advantage of using the debugger is that you do not have to add debug code, correct the debug code, rebuild, and rerun with the traces.

BTW - Where you place your file is sometimes a little tricky when running with the debugger. In this case, I put your "Book1.csv" file, not in the solutions folder, but in the project folder.
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
debuggers are definitely good. But in this case since the problem occurs intermittently it might be a better bet to use logging. As I mentioned earlier have a go at the following link to get an overview about where things could be going wrong.

http://www.cprogramming.com/debugging/segfaults.html

As  infinity has already pointed out you could be having a stack overflow due to the recursions in your logic and this could be a cause for the Seg fault.

See my snippet below on how to add the debug statements
wofstream out;
out.open("MyLogs.txt",ios::app);

data.push_back( vector <string>() );
out<<"Initialized data\n";

      while( in.read( (char*)&ch, 1 ) )
      {
       out<<"Entered while and reading char"<<ch<<"\n";
           ...
            ...
             //place similar logging statements in places wherever you feel appropriate.
             //also print the value of variables like I've shown above.

Open in new window

0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 132 total points
Comment Utility
>> since the problem occurs intermittently
fyi - It always failed with an exception in csv::write() using my two line csv file.
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 100 total points
Comment Utility
>> I’m very new to C++, can you give me code example how to fix the issue

Which of the issues are you referring to ?

Were you able to confirm my suspicion that not all lines in the csv file contain the same amount of delimiters ? A reason for this could be a field containing a comma.

Alternatively, you could post a sample csv file, and indicate at which line the issue occurs.
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 132 total points
Comment Utility
>> my suspicion that not all lines in the csv file contain the same amount of delimiters
Well there possibly could be other problems, but this is definitely one of them. The input is flexible in that it has no problem dealing with different number of columns for each row. And the number of rows is certainly universal. But, if the flexibility is for a ragged array is desired, then the number of columns needs to be dealt with on a row by row basis in in csv::write(), as in:
    int cols = data[x].size();
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 100 total points
Comment Utility
>> Well there possibly could be other problems,

I've pointed out a few in my first post ;)
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
Comment Utility
"fyi - It always failed with an exception in csv::write() using my two line csv file."
 -- my results were intermittent. Besides we have to go with what the problem reporter tell us. What was the exception you got?

habte : have your tried out the suggestions? Have you added logging and tried out a few runs with differing csv files....
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now