Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Segmentation Fault Error C++

Posted on 2010-09-15
17
Medium Priority
?
773 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 4
  • 3
  • +1
17 Comments
 
LVL 53

Accepted Solution

by:
Infinity08 earned 400 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 1072 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 12

Assisted Solution

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

Assisted Solution

by:trinitrotoluene
trinitrotoluene earned 1072 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 1072 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 528 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 528 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 1072 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 528 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 400 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 528 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 400 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 1072 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

Tech or Treat! - Giveaway

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

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

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

636 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