简体   繁体   中英

Segmentation Fault Before main()

I'm having a problem with this code. After compiling with g++, I run a.out and I get a segmentation fault and no "here" displayed. The code is pretty short:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;

bool inWords(vector<string> words, string str);

int main()
{
  cout << "here";

  vector<string> words;
  string str;
  istringstream iss;
  ifstream file("data.txt", ifstream::in);

  // read in words
  for(int i = 0; file >> str; /*no i++*/)
  {
    if(str[str.length() - 1] == '.')
      str.erase( str.length()-1);
      // if word has a period at the end, erase it

    if(!inWords(words, str))
    {
      // if word is not in vector words, add it
      words.push_back(str);
      i++;
    }
  }

  // output each word
  for (vector<string>::size_type i = 0; i < words.size(); i++)
    cout << words[i];

  // return to beginning of file
  file.clear();
  file.seekg(0, ios::beg);

  // read in sentences
  // to be implemented

  file.close();

  return 0;
}

bool inWords(vector<string> words, string str)
{
  for(int i = 0; !words[i].empty(); i++)
    if(words[i] == str) { return true; }
  return false;
}

As far as I know, nothing should be a problem. data.txt is definitely in the same directory as the file and I receive no arguments from the command line. Can anyone help?

It won't be before main. Try using a debugger to see where it happens (eg GDB) which are incredibly handy tool. The reason you don't see "here" is because the buffer isn't flushed. Put a << std::endl after it so that it forces output at that point.

A technicality: You can segfault before main but that will happen in a constructor. I see you have no custom objects defined/instantiated in global scope.

The technique for iterating the vector in inWords is wrong and interacts with elements past the end of the vector causing the segmentation fault.

This program immediately accesses words[0] in inWords when the words vector is empty and words[0] (the first element of the vector) does not exist yet because the size of the vector is still zero but the loop does not do anything to avoid this condition.

I think inWords could be better implemented with std::find , perhaps like this:

bool inWords(const vector<string>& words, const string& str)
{
  return std::find(words.begin(), words.end(), str) != words.end();
}

Remember to #include <algorithm> to make use of std::find . I also changed the parameters to pass by const reference, so you'll need to change the forward declaration of that function. I also added an endl to the output to make it readable.

Full text of repair:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;

bool inWords(const vector<string>& words, const string& str);

int main()
{
  vector<string> words;
  string str;
  istringstream iss;
  ifstream file("data.txt", ifstream::in);

  // read in words
  for(int i = 0; file >> str; /*no i++*/)
  {
    if(str[str.length() - 1] == '.')
      str.erase( str.length()-1);
      // if word has a period at the end, erase it

    if(!inWords(words, str))
    {
      // if word is not in vector words, add it
      words.push_back(str);
      i++;
    }
  }

  // output each word
  for (vector<string>::size_type i = 0; i < words.size(); i++)
    cout << words[i] << std::endl;

  // return to beginning of file
  file.clear();
  file.seekg(0, ios::beg);

  // read in sentences
  // to be implemented

  file.close();

  return 0;
}

bool inWords(const vector<string>& words, const string& str)
{
  return std::find(words.begin(), words.end(), str) != words.end();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM