2016-12-08 4 views
-2

Chaque fois que j'exécute mon programme, une exception std::bad_alloc est générée, ce qui provoque un abandon. Le std::bad_alloc est levé uniquement lorsque va_arg est appelé. La chose étrange est le code que les accidents ont été fournis par l'instructeur. Je n'ai pas écrit la ligne qui se bloque. Valgrind me dit que cela est dû à new/new[]. Pourquoi va_arg cause cela? Le bad_alloc se produit UNIQUEMENT quand il s'exécute (ce qu'il fait à d'autres endroits aussi).va_arg provoque std :: bad_alloc

void Library::addKeywordsForItem(const Item* const item, int nKeywords, ...) 
{ 
    // the code in this function demonstrates how to handle a vararg in C++ 

    va_list   keywords; 
    string   keyword = "test"; 
    bool   successFlag = false; 
    sArray   keywordV; 
    cout << "Before lookupItem\n"; 
    Item*   item2 = lookupItem(item); 
    cout << "After lookupItem\n"; 

    va_start(keywords, nKeywords); 
    cout << "after va_start\n"; 
    for (int i = 0; i < nKeywords; i++) //this code adds the items to a map of set to create a fast access structure for keyword searches 
    { 
     cout << "before keyword assign\n"; 
     keyword = va_arg(keywords, string); //Crash here 
     cout << "after keyword assign\n"; 
     // do something with each keyword 
     cout << "before HERE\n"; 
     keywordV.push_back(keyword); //pushes keyword onto vector 
     cout << "HERE\n"; 
     successFlag = addToSMap(item, keyword, keywordDbase); //This function is literally a copy/paste of the code 
     //originally designed for this function 
    } 
    va_end(keywords); 

    //Sets in keywords 
    item2->setKeywords(keywordV); 

    if(!successFlag) //Should never execute 
     cout << "This code reeks verily of wrongness.\n"; 
} 

Le code ci-dessus est appelé de l'instructeur suivant la ligne écrite du Code

library->addKeywordsForItem(item, 2, "autism", "Asperger's Syndrome"); 

Voici les erreurs que je reçois

Valgrind

**5851** new/new[] failed and should throw an exception, but Valgrind 
**5851** cannot throw exceptions and so is aborting instead. Sorry. 
==5851== at 0x4C275AC: ??? (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==5851== by 0x4C27DC6: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==5851== by 0x4F57496: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.tcc:265) 
==5851== by 0x4F577E8: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:1181) 
==5851== by 0x4085F8: Library::addKeywordsForItem(Item const*, int, ...) (Library.cpp:79) 
==5851== by 0x401BB5: main (Asgmt04.cpp:38) 

Programme

Mettre fin à appelé après avoir jeté une instance de 'std :: bad_alloc'
ce(): std :: bad_alloc Aborted

L'instructeur a conçu la boucle qui utilise les va_args (je viens Complété ce qu'il fait) donc je ne sais pas pourquoi son code provoque un crash. Mon code provoque-t-il un crash? Quelqu'un pourrait-il donner un aperçu?

+0

Si vous avez C++ 11 avec des modèles variés, pourquoi utiliser 'va_args'? –

+0

C'est ce que l'instructeur veut que nous utilisions. –

+1

Les paramètres supplémentaires des variables 'chaîne' actuelles' addKeywordsForItem' sont-ils des paramètres supplémentaires ou sont-ils des "chaînes de caractères"? – 1201ProgramAlarm

Répondre

4

"autism" et "Asperger's Syndrome" sont const char * valeurs, non string valeurs, donc essayer de les lire comme causes de comportement non défini de string.

+0

@Stargateur Voulez-vous utiliser 'const int', car il est important de savoir que 10 ne peut pas être modifié? [sic] – immibis

+0

@Stargateur Vous avez le droit d'aimer Rust mais C++ n'est pas Rust. – immibis

+0

@Stargateur Je veux dire que différentes langues ont des conventions différentes. La convention en C++ n'est pas de mettre const sur tout ce qui est possible. 'std :: string const &' est utile car il peut se référer à une variable const 'std :: string', une variable non-const, ou une variable temporaire; c'est une différence significative qui justifie l'utilisation de 'const'. – immibis