2012-05-28 2 views
3

Я разделив строку в вектор строкC++ ошибка сегментации строки расщепления

vector<string> tokens; 

    stringstream strstm(str); 
    string item; 
    while (getline(strstm, item, ' ')) { 
     tokens.push_back(item); 
    } 

    token_idx = 0; 

    cout << "size = " << tokens.size() << endl; 

    for (unsigned int i = 0; i < tokens.size(); i++) 
    { 
     cout << tokens[i] << "[" << i << "]" << endl; 
    } 

Раскол успешно, и размер() и его элементы, что мне нравится, что это будет. Однако последний токен, кажется, действует странно, когда я пытаюсь получить его значение.

string Lexer::consume() { 
    if (hasValue()) { 
     token_idx++; 
     cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl; 
     return tokens[token_idx-1]; 
    } 
    cout << "didn't consume, token_idx = " << token_idx << endl; 
    return "null"; 
} 

hasVal подобно этому

bool Lexer::hasValue() { 
    if (token_idx < tokens.size()) { 
     return true; 
    } else { 
     return false; 
    } 
} 

, если у меня есть входная строка, как такой 1 + 2 * 3 ожидаемый выход из моей программы должен быть (+1(*23)), однако я получаю ошибку сегментации.

size = 5 
1[0] 
+[1] 
2[2] 
*[3] 
3[4] 
consumed 1 tokens = 0 
consumed + tokens = 1 
consumed 2 tokens = 2 
consumed * tokens = 3 
consumed 3 tokens = 4 
Segmentation fault (core dumped) 

Но если я изменить имеет контрольное значение для (token_idx < tokens.size() -1), программа будет возвращать (+1 (*2 null))

size = 5 
1[0] 
+[1] 
2[2] 
*[3] 
3[4] 
consumed 1 tokens = 0 
consumed + tokens = 1 
consumed 2 tokens = 2 
consumed * tokens = 3 
didn't consume, token_idx = 4 
(+1 (*2 null)) 

Так мне интересно, если есть конец строки после 3 при разделении так, что я были или есть некоторые другие факторы, способствующие этому поведению? Я совершенно уверен, что я не выхожу за рамки для вектора.

+0

На какой линии он падает? –

+0

Я использовал gdb в файле дампа ядра, однако информация, которую он мне дает, довольно расплывчата и не говорит мне, какая строка в моем коде разбилась. с использованием команды 'gdb prefixer core.3211' Я получаю . Ядро было создано' ./prefixer '. Программа завершена сигналом 11, Ошибка сегментации. # 0 0x0000003b1229c0d3 в std :: basic_string , std :: allocator > :: size() const() из /usr/lib64/libstdc++.so.6 Отсутствует отдельный debuginfos, используйте: debuginfo-install glibc-2.12-1.47.el6_2.12.x86_64 libgcc-4.4.6-3.el6.x86_64 libstdC++ - 4.4.6-3.el6.x86_64' –

+0

Собираетесь ли вы с g ++? Использование опции -g? –

ответ

1

Я думаю, что реальный инкриминируемый код, генерирующий ошибку, не показал ее, но поскольку я могу понять, как вы манипулируете индексом ... нет никакой ошибки, что вы сделали ошибку, проходящую мимо конца вашего списка токенов, Кроме того, с учетом склонности к ошибкам дизайн, вот и все.

if (hasValue()) { // has value is useless to me 
    token_idx++; // why incrementing this here ? 

    cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl; 

    return tokens[token_idx-1]; 
} 

изменить его к этому:

if (token_idx < tokens.size()) { 
    cout << "consumed " << tokens[token_idx] << " tokens = " << token_idx << endl; 

    return tokens [ token_idx++ ]; 
} 

Читайте также о recursive descent parsing, это действительно просто, и вы будете гораздо больше информированы о разборе, избегая распространенных ошибок.

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