2014-02-27 3 views
0

Я разбираю текстовый файл со словом и тегом (выглядит как слово/тег). Я пытаюсь найти количество уникальных тегов в моем файле и использую неупорядоченный набор в C++ для вставки тегов. Однако, похоже, я случайно получаю это исключение: «EXC_I386_GPFLT» при вставке (после неопределенного количества вставок) в мой неупорядоченный набор. Я не думаю, что у меня заканчивается память, потому что Xcode говорит, что я использую только ~ 300 - 400 KBЕсть ли ограничение на размер неупорядоченного набора в C++

Вот моя главная функция:.

#include <iostream> 
#include "ParseTrain.h" 

int main(int argc, const char * argv[]) 
{ 
    ParseTrain p("~/Desktop/treebank.5290.train"); 
    std::cout<<"The Number of Tags is: "<<p.getSizeOfTag()<<std::endl; 
    return 0; 
} 

Вот мой ParseTrain.cpp:

#include "ParseTrain.h" 
#include <fstream> 
#include <string> 
#include <iostream> 


ParseTrain::ParseTrain(std::string fName){ 
    std::ifstream file(fName); 
    std::string word; 

    if(!file) 
     return; 

    //read file by word 
    while(file >> word){ 
     char * cWord = new char (word.size()+1); 
     std::strcpy(cWord,word.c_str()); 

     char *p = std::strtok(cWord, "/"); 
     std::string key = p; 
     p = strtok(NULL, " "); 
     std::string value = p; 
     std::cout<<value<<std::endl; 
     _tag.insert(value);//getting exception thrown after undeterminable number of inserts at this line 
     delete [] cWord; 
     cWord = NULL; 
    } 
} 

Вот мой ParseTrain.h:

#include <iostream> 
#include <map> 
#include <string> 
#include <vector> 
#include <unordered_set> 

class ParseTrain{ 
private: 

    //map to relate the work and part of speech tag 
    std::vector <std::map<std::string, std::string>> _sentence; 
    std::unordered_set<std::string> _tag; 
public: 

    //constructor to parse file 
    //takes in path to file to parse 
    ParseTrain(std::string fName); 

    inline size_t getSizeOfTag(){ 
     return _tag.size(); 
    } 
}; 

И, наконец, вот небольшая часть текстового файла я пытаюсь разобрать и получить тег:

Pierre/NP Vinken/NP ,/, 61/CD years/NNS old/JJ ,/, will/MD join/VB the/DT board/NN as/IN a/DT nonexecutive/JJ director/NN Nov./NP 29/CD ./. 
Mr./NP Vinken/NP is/VBZ chairman/NN of/IN Elsevier/NP N.V./NP ,/, the/DT Dutch/NP publishing/VBG group/NN ./. 

Я действительно не могу понять, почему исключение бросает при вставке. Единственное, о чем я могу думать, это ограничение размера неупорядоченного набора, но это кажется странным, учитывая, что я использую такую ​​небольшую память. Любая помощь будет принята с благодарностью.

+0

Всегда есть предел. Но, скорее всего, вы пытаетесь читать из значения, когда * P == nullptr. Сократите свою строку и просто используйте последнюю часть. Тогда это не займет столько времени, чтобы пройти через код и осмотреть местных жителей. Вы должны обработать случай, когда strtok возвращает null. – Dan

+1

Память не может быть поистине неограниченной, но код, заполненный 'strtok', raw' new' и raw 'delete', приводит к гораздо более вероятным целям. –

+0

Очевидный способ отладки этого заключается в том, чтобы поместить некоторую проверку ошибок в код разбора: после 'strtok' вы просто предполагаете, что указатели не являются NULL - что, если на входе есть плохая строка? Вы можете добавить счетчик, чтобы вы знали, какая строка ввода - полезная, если печать каждой строки слишком медленная, чтобы быть практичной (даже для файла или «хвоста»). Еще лучше используйте 'std :: string :: find' и' erase' или 'substr' для извлечения значения. –

ответ

4

Это:

char * cWord = new char (word.size()+1); 

должен быть таким:

char * cWord = new char [word.size()+1]; 

Примечание скобки.

Первый выделяет один байт и инициализирует его до word.size()+1. Второй выделяет word.size()+1 байт.

+0

yup, что исправил это! благодаря! – user2604504

Смежные вопросы