简体   繁体   English

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

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

This is my school program that crashes on me, probably something from (Segmentation fault / Bus error / Memory limit exceeded / Stack limit exceeded).这是我的学校程序崩溃了,可能来自(分段错误/总线错误/Memory 超出限制/超出堆栈限制)。 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]以 [name] [surname] [number] 的形式从文件中检索信息

Martin Jeff 123456789马丁杰夫 123456789

Tomas Adam 234567890托马斯·亚当 234567890

This is followed by a blank line [\ n]后面跟一个空行 [\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): Test0(工作正确):

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

John
Martin
Dakhov
Harmson

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'.原因是您从不在“报告”中写入输出 stream。

The reason it fails with a larger data set is due to this function它因更大的数据集而失败的原因是这个 function

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

This function does nothing.这个 function 什么都不做。 It allocates a new larger array of Uzi objects, then deletes it.它分配一个新的更大的 Uzi 对象数组,然后删除它。 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 std::vector 会更好,它会为你做这一切

Also why read the whole file into memory as a stringstream then read the stringstream, why not use the file stream directly?还有为什么把整个文件读入memory作为stringstream再读stringstream,为什么不直接使用文件stream呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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