簡體   English   中英

C++(分段錯誤/總線錯誤/Memory 超出限制/超出堆棧限制)

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

這是我的學校程序崩潰了,可能來自(分段錯誤/總線錯誤/Memory 超出限制/超出堆棧限制)。 我不知道錯誤在哪里。 我試着評論代碼並減少它一點。

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

Test0(工作正確):

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

John
Martin
Dakhov
Harmson

您使用您提供的輸入數據(那兩行)發布的代碼有效,但第二個斷言失敗。 原因是您從不在“報告”中寫入輸出 stream。

它因更大的數據集而失敗的原因是這個 function

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

這個 function 什么都不做。 它分配一個新的更大的 Uzi 對象數組,然后刪除它。 我認為它實際上是在嘗試刪除太小的舊版本

刪除舊指針后應返回新指針。

std::vector 會更好,它會為你做這一切

還有為什么把整個文件讀入memory作為stringstream再讀stringstream,為什么不直接使用文件stream呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM