0

I have written some code in c++. It reads in data from a CSV file and then simply prints the second line to the screen:

vector<string> readCsvFileContent()
{
    vector<string> buffer;

    try {
        ifstream inputFile;
        string line;

        inputFile.open("Input.csv", static_cast<std::ios::openmode>(std::ios::in) );

        while (getline(inputFile,line)) {
            buffer.push_back(line);
        }

       inputFile.close();
    }
    catch (ifstream::failure e) { 
        cout<<"No file read"<<endl;            
        throw e;
    }

    return buffer;
}

This function is called as follows :

cout << "reading from file" << endl;
vector<string> inputData = readCsvFileContent();
cout << inputData.size() << endl;
cout << inputData[1] << endl;

When it runs in debug it displays what it should:

[ 50%] Building CXX object src/CMakeFiles/version1.dir/version1.cc.o
Linking CXX executable version1
[ 50%] Built target version1
[100%] Generating House1.csv
reading from file
322274
"2014-07-01 00:00:06",155,0,0,0,NULL,0,0,0,0,NULL
[100%] Built target process_csv

But when I run my code I get:

reading from file
0
Segmentation fault (core dumped)
15
  • 1
    @lurker No it's returned from the function by value. That's fine. Commented Feb 2, 2015 at 12:31
  • 2
    Do not cast the opening method. What for are you doing it? Just open(file,mode) Commented Feb 2, 2015 at 12:32
  • 1
    Your problem lies outside of the function you posted. Commented Feb 2, 2015 at 12:38
  • 2
    @Lands the main function, combined with the output, reveals why the segfault happens. Your main prints the size of the vector which is 0 in the output. Therefore inputData[1] has undefined behaviour. So, the problem is that either the file is empty, doesn't exist or isn't readable. Perhaps you're running your debug and release builds differently? Maybe they have different working directories and only debug actually has the file? Perhaps the file exists in the release directory with wrong permissions. Your code really should check that it has actually opened a (non-empty) file. Commented Feb 2, 2015 at 13:00
  • 1
    You don't know how many lines are in a file. Therefore don't hardcode a line access without checking the size first. Commented Feb 2, 2015 at 13:31

1 Answer 1

4

You get a segfault because you read beyond the vectors borders

inputData.size() // 0 i.e. empty
inputData[1] // undefined behaviour

Your code should check whether a file was opened succesfully. You can do this:

if (!inputFile.is_open())
    // throw or whatever

Or, since you seem to already be prepared for it with a try-catch, as molbdnilo points out, you can ask the stream to throw on failure:

inputFile.exceptions(std::ifstream::failbit);

To test if the file was empty, just check inputData.size() which you already print, but ignore.

Now, the remaining question is, why does it work in debug but not in release? Well, my crystal ball is out of battery but I can speculate that your builds have different working directories and the file is missing or not readable in the other one. You haven't told about what your build does but this might be relevant:

[100%] Generating House1.csv

inputFile.open("Input.csv", static_cast(std::ios::in) );

Sign up to request clarification or add additional context in comments.

1 Comment

This is the right answer. I should have waited for the edit :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.