Solved

Segmentation Fault Error C++

Posted on 2010-09-15
17
734 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
ID: 33687410
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
ID: 33687649
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
ID: 33687713
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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
ID: 33687727
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
ID: 33687782
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
ID: 33687902
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
ID: 33687910
i hope u entered semi colons, and removed all those ...
0
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
ID: 33687955
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
 
LVL 12

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 268 total points
ID: 33687957
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
ID: 33688037
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
ID: 33688055
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
ID: 33688678
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
ID: 33688706
>> 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
ID: 33691357
>> 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
ID: 33691414
>> 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
ID: 33691442
>> 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
ID: 33699017
"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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

776 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