2017-01-02 2 views
1

Je rencontre un problème lors de l'exécution du code ci-dessous. Chaque fois que je mets la boucle while pour atteindre le .EOF() retourne un std :: bad_allocPourquoi ai-je une erreur std :: bad_alloc?

inFile.open(fileName, std::ios::in | std::ios::binary); 

     if (inFile.is_open()) 
     { 
      while (!inFile.eof()) 
      { 
       read(inFile, readIn); 
       vecMenu.push_back(readIn); 
       menu.push_back(readIn); 
       //count++; 
      } 

      std::cout << "File was loaded succesfully..." << std::endl; 

      inFile.close(); 
     } 

Il fonctionne très bien si je fixe un nombre prédéterminé d'itérations, mais échoue lorsque j'utilise le funtion EOF. Voici le code pour la fonction de lecture:

void read(std::fstream& file, std::string& str) 
{ 
    if (file.is_open()) 
    { 
     unsigned len; 
     char *buf = nullptr; 

     file.read(reinterpret_cast<char *>(&len), sizeof(unsigned)); 

     buf = new char[len + 1]; 

     file.read(buf, len); 

     buf[len] = '\0'; 

     str = buf; 

     std::cout << "Test: " << str << std::endl; 

     delete[] buf; 
    } 
    else 
    { 
     std::cout << "File was not accessible" << std::endl; 
    } 
} 

Toute aide que vous pouvez fournir est grandement appréciée. NOTE: Je ne mentionnais pas que vecMenu est de type std :: vecteur et le menu est de type std :: Liste

+3

S'il vous plaît voir ce post: [? Pourquoi iostream :: eof dans une condition de la boucle considérée comme erronée] (http://stackoverflow.com/questions/ 5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Rakete1111

+0

Merci @ Rakete1111 – Akatosh

+1

De plus, appeler l'allocateur pour chaque ligne que vous lisez ralentit votre programme. Mieux vaut utiliser un 'std :: vector' non local et émettre un appel' resize() 'que d'émettre des appels' new/delete' à chaque fois. – PaulMcKenzie

Répondre

1

Les principaux problèmes que je vois sont:

  1. Vous utilisez while (!inFile.eof()) pour mettre fin à la boucle. Voir Why is iostream::eof inside a loop condition considered wrong?.

  2. Vous ne vérifiez pas si les appels à ifstream::read ont réussi avant d'utiliser les variables qui ont été lues.

Je propose:

  1. Changer votre version de read pour renvoyer une référence à ifstream. Il devrait retourner le ifstream qu'il prend en entrée. Cela permet d'utiliser l'appel à read au conditionnel d'une boucle.

  2. Vérifie si les appels à ifstream::read réussissent avant de les utiliser.

  3. En mettant l'appel à read dans le conditionnel de l'instruction while.

std::ifstream& read(std::fstream& file, std::string& str) 
{ 
    if (file.is_open()) 
    { 
     unsigned len; 
     char *buf = nullptr; 

     if !(file.read(reinterpret_cast<char *>(&len), sizeof(unsigned))) 
     { 
     return file; 
     } 

     buf = new char[len + 1]; 

     if (!file.read(buf, len)) 
     { 
     delete [] buf; 
     return file; 
     } 

     buf[len] = '\0'; 

     str = buf; 

     std::cout << "Test: " << str << std::endl; 

     delete[] buf; 
    } 
    else 
    { 
     std::cout << "File was not accessible" << std::endl; 
    } 

    return file; 
} 

et

inFile.open(fileName, std::ios::in | std::ios::binary); 

if (inFile.is_open()) 
{ 
    std::cout << "File was loaded succesfully..." << std::endl; 

    while (read(inFile, readIn)) 
    { 
     vecMenu.push_back(readIn); 
     menu.push_back(readIn); 
     //count++; 
    } 

    inFile.close(); 
}