Home > Software design >  C (Segmentation fault / Bus error / Memory limit exceeded / Stack limit exceeded)
C (Segmentation fault / Bus error / Memory limit exceeded / Stack limit exceeded)

Time:03-07

This is my school program that crashes on me, probably something from (Segmentation fault / Bus error / Memory limit exceeded / Stack limit exceeded). I can't figure out where the mistake is. I tried to comment on the code and reduce it a bit.

Retrieving information from the file in the form [name] [surname] [number]

Martin Jeff 123456789

Tomas Adam 234567890

This is followed by a blank line [\ n]

And then I search by the entered name, surname or both

Martin

Thomas

Adam

Martin Jeff

...

Thank you in advance for your advice.

class Uzivatel
{
    public:
        string name;
        string surname;
        string number;
};

void alocation(int &velPole, Uzivatel *arr)
{
    velPole = 2*velPole;
    Uzivatel *tmp = new Uzivatel[velPole];
    arr = tmp;
    delete []tmp;
}


void getString(const string & fileName, ostream &strStream)
{
    ifstream ifs;
    ifs.open(fileName);
    
    if(ifs.is_open())
    {
        strStream << ifs.rdbuf();
        ifs.close();
    }
}

void finding(int pocet, Uzivatel *uzivatele, ostream &out, string &line)
{
    string name = "";  string surname = ""; string number = "";
    int matches = 0;

    stringstream s(line);
    s >> name >> surname >> number;

    if(!(surname.compare("")))
      surname = name;
              
    for(int i=0; i<pocet; i  )
    {
        if( (!name.compare(uzivatele[i].name)) || (!surname.compare(uzivatele[i].surname)) )
          {
            out << uzivatele[i].name << " " << uzivatele[i].surname << " " << uzivatele[i].number << endl;
            matches   ;
          }
    }
    out << "-> " << matches <<endl;
}

bool isValid(string &jmeno, string &prijmeni, string &cislo)
{
  int x = cislo.find_first_not_of("0123456789");
  int y = cislo.length(); 
  
  if((!x) || cislo[0] == '0' || y != 9 || jmeno=="" || prijmeni=="" || cislo=="" )
    return false;

  return true;
}

bool report ( const string & fileName, ostream & out )
{
    
    ifstream ifs;
    stringstream strStream;
    getString(fileName, strStream);

    int arrLen = 200;
    Uzivatel *uzivatele = new Uzivatel[arrLen];
    int arrElem = 0;

    string line;
    bool hledani = false;

    while (getline(strStream, line))
    {
        if(hledani)
        { 
            finding(arrElem, uzivatele, out, line);   
        }
        else
        {
            stringstream s(line);

            string konec = "";
            s >> uzivatele[arrElem].name >> uzivatele[arrElem].surname >> uzivatele[arrElem].number >> konec;

            /* If there was anything else at the entrance*/
            if(konec!="")
            {
              delete []uzivatele;
              return false;
            }
            
            /* Realloc */
            if(arrElem == arrLen)
              alocation(arrLen, uzivatele);
                      
            arrElem  ;

            /* Enter'\n' */
            if(!line.compare(""))
                {
                    hledani = true;
                    arrElem--;

                    /* Validation enter */
                    for(int i=0; i<arrElem;i  )
                    {
                        if(!(isValid(uzivatele[i].name, uzivatele[i].surname, uzivatele[i].number)))
                        {
                          delete []uzivatele;
                          return false;
                        }
                    }
                }
        }

    }
    if(!hledani)
    {
      delete []uzivatele;
      return false;
    }
    delete []uzivatele;
    return true;
}

int main ()
{
  ostringstream oss;
  oss . str ( "" );
  assert ( report( "tests/test0_in.txt", oss ) == true );
  assert ( oss . str () ==
    "John Christescu 258452362\n"
    "John Harmson 861647702\n"
    "-> 2\n"
    "-> 0\n"
    "Josh Dakhov 264112084\n"
    "Dakhov Speechley 865216101\n"
    "-> 2\n"
    "John Harmson 861647702\n"
    "-> 1\n" );
  oss . str ( "" );
  assert ( report( "tests/test1_in.txt", oss ) == false );

  return 0;
}

Test0 (Work correct):

John    Christescu  258452362
Peter   Herreran    716973426
Josh    Dakhov  264112084
John    Harmson 861647702
Dakhov  Speechley   865216101

John
Martin
Dakhov
Harmson

CodePudding user response:

You code as posted with the input data you gave (those 2 lines) works, except that the second assert fails. The reason being that you never write to the out stream in 'report'.

The reason it fails with a larger data set is due to this function

void alocation(int& velPole, Uzivatel* arr)
{
    velPole = 2 * velPole;
    Uzivatel* tmp = new Uzivatel[velPole];
    arr = tmp;
    delete[]tmp;
}

This function does nothing. It allocates a new larger array of Uzi objects, then deletes it. I assume its actually trying to delete the old one thats too small

You should return the new pointer after deleting the old one.

Much better would be std::vector which will do this all for you

Also why read the whole file into memory as a stringstream then read the stringstream, why not use the file stream directly?

  • Related