1

Я работаю над базовым калькулятором, который может принимать сложные математические выражения, такие как: (2-4) * 7/(3/4) и т. Д. И т. Д.Ошибка сегментации при назначении строки stack.top()

Я использую реализацию алгоритма маневрового двора ...

Я нахожусь в операционной системе Linux. используя отладчик gdb, я выделил ошибку сегментации для одной функции. using заявления cout Я выделил его дальше к одной строке ... я не могу понять, почему эта строка дает мне segfault. Я дам больше информации о том, где именно через мгновение, сначала вот какой-то код.

bool infixToPostfix(const std::vector<std::string>& inputTokens, const int& size, std::vector<std::string>& strArray){ 
    std::cout << "1" << std::endl; 
    bool success = true; 
    std::list<std::string> out; 
    std::stack<std::string> st; 

for(int i = 0; i < size; i++){ 
    std::cout << "2\n"; 
    const std::string token = inputTokens[i]; 

    if(isOperator(token)){ 
     std::cout << "3\n"; 
     const std::string o1 = token; 

     if(!st.empty()){ 
      std::cout << "4\n"; 
      std::string o2 = st.top(); 

      while(isOperator(o2) && ((isAssociative(o1, LEFT_ASSOC) && cmpPrecedence(o1, o2) == 0) || (cmpPrecedence(o1, o2) < 0))){ 
       std::cout << "5\n"; 
       st.pop(); 
       out.push_back(o2); 

       if(!st.empty()){ 
        std::cout << " 6\n";  
        o2 = st.top(); 
       } 
       else{ 
        std::cout << "7\n"; 
        break; 
       } 
      }  
     } 
     std::cout << "8\n"; 
     st.push(o1); 
    } 
    else if(token == "("){ 
     std::cout << "9\n"; 
     st.push(token); 
    } 
    else if(token == ")"){ 
     std::cout << "10\n"; 
     std::string topToken = st.top(); 

     while(topToken != "("){ 
      std::cout << "11\n"; 
      out.push_back(topToken); 
      st.pop(); 

      if(st.empty()){ 
       std::cout<< "12\n"; 
       break; 
      } 
      std::cout << "13\n"; 
      topToken = st.top(); 
     } 
     if(!st.empty()){ 
      std::cout << "14\n"; 
      st.pop(); 
     } 
     if(topToken != "("){ 
      std::cout << "15\n"; 
      return false; 
     } 
    } 
    else{ 
     std:: cout << "16\n"; 
     out.push_back(token); 
    } 
} 
while(!st.empty()){ 
    std:: cout << "17\n"; 
    const std::string stackToken = st.top(); 

    if(isParentheses(stackToken)){ 
     std::cout << "18\n"; 
     return false; 
    } 
    std::cout << "19\n"; 
    out.push_back(stackToken); 
    st.pop(); 
} 
std::cout << "20\n"; 
strArray.assign(out.begin(), out.end()); 
return success; 
} 

выдаёт ошибку сегментации происходит в std::cout << "10\n"; при вызове std::string topToken = st.top();

я дам некоторые входы/выходы

intput: (8*2) выходы: 1 2 9 2 3 4 8 2 3 4 5 6 8 2 10 11 13 14 2 10 segfault (core dumped)

вход: (4/4) выход: 1 2 9 2 3 4 8 2 3 4 5 6 8 2 10 11 13 14 2 10 segfault (core dump)

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

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

P.S: любые опечатки в коде являются опечатками! Я скопировал код, переименовав его, так как я кодирую ОС Linux, но у меня есть компьютер. С учетом сказанного ... код компилируется без ошибок, любые орфографические термины - это опечатки !!

еще раз спасибо

EDIT: после того, придав ему несколько дней, и возвращаться к этому я пробежал еще несколько тестов на коде. На этот раз используя уравнения без круглых скобок.

вход: 3-9 выход: 1 2
3 8 2 3 4 5 7 8 17 19 20 segfault (core dump)

вход: 6/8 выход: 1 2 3 8 2 3 4 5 7 8 17 19 20

Таким образом, я также получаю Segfault при вызове strArray.assign(out.begin(), out.end());

+2

Вы, кажется, доверяете правилу 'size'. Если бы я был вами, я бы проверил размер по отношению к векторам, к которым вы обращаетесь через [i]. Я предполагаю, что вы убежали от конца вектора. – codenheim

+0

Во-вторых, его легко скомпоновать с помощью электрического заграждения или запустить под контролем valgrind (если у вас установлены пакеты, если они не являются стандартными пакетами, используйте yum или любой другой инструмент пакета, соответствующий их установке). – codenheim

ответ

0

Добавьте следующий после строки const std::string token = inputTokens[i];:

std::cout << "inputTokens[" << i << "]: " << token << std::endl; 

Я думаю, вы обнаружите, что есть проблема с вектором inputTokens или, возможно, с size.

Из любопытства - почему вы проходите в size в качестве аргумента вместо использования inputTokens.size()?

+0

большое спасибо. Проведя намного больше тестирования, я обнаружил, что проблема связана с моим токенизатором. И я использовал его в качестве аргумента из предложения моего друга, я не помню, почему я так долго работал над этим. – mpdambra