C++(分段错误/总线错误/超出内存限制/超出堆栈限制)

C++ (Segmentation fault / Bus error / Memory limit exceeded / Stack limit exceeded)

这是我的学校程序在我身上崩溃,可能是由于(分段错误/总线错误/超出内存限制/超出堆栈限制)。我不知道错误在哪里。我尝试对代码进行评论并减少它。

正在从格式为[name] [surname] [number]

的文件中检索信息

马丁·杰夫 123456789

托马斯·亚当 234567890

后面跟一个空行[\n]

然后我按输入的姓名、姓氏或两者进行搜索

马丁

托马斯

亚当

马丁·杰夫

...

预先感谢您的建议。

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;
}

测试 0(工作正确):

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

John
Martin
Dakhov
Harmson

您使用您提供的输入数据(那两行)发布的代码有效,除了第二个断言失败。原因是您从不写入 'report'.

中的输出流

它在更大的数据集上失败的原因是这个函数

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

这个函数什么都不做。它分配一个新的更大的 Uzi 对象数组,然后删除它。我假设它实际上是在尝试删除太小的旧版本

你应该return删除旧指针后的新指针。

std::vector 会更好,它会为您完成这一切

还有为什么把整个文件以stringstream的形式读入内存然后读取stringstream,为什么不直接使用文件流呢?