Получение ошибки при зачатии

#c #arrays #segmentation-fault #uart

Вопрос:

Я получаю строковые данные из UART и преобразую их в шестнадцатеричный формат. После преобразования в шестнадцатеричный формат у меня есть два уникальных разделителя «06» и «07». Я хочу получить данные между этими двумя разделителями. Я попытался построить приведенный ниже код на основе того, что я сказал. Но после получения 6-7 выходных данных я получаю ошибку ошибки сегментации.

  std::string sub_between(std::string start,std::string stop,std::string input)
    {
       auto start_index = input.find(start);
       if (start_index != std::string::npos) 
       {
          auto stop_index = input.find(stop,start_index start.size());
          if (stop_index != std::string::npos)
          {
            return {input.begin()   start_index start.size(), input.begin()   stop_index};
          }
       }
        //  return empty string
        return {};
    }

    int main(int argc, char ** argv) 

{
  int uart0_filestream = -1;
  int uart2_filestream = -1;
  unsigned char rx_buffer[1024];
  memset(amp;rx_buffer[0], 0, 1023);

  unsigned char tx_buffer[1024];
  memset(amp;tx_buffer[0], 0, 1023);

  std::stringstream ss;


  if(uart0_filestream == -1)
  {
    uart0_filestream = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    //uart0_filestream = open("/dev/ttyS0", O_NOCTTY );
    
    if(uart0_filestream == -1)
    {
        std::cout << "UARTListener::Start Unable to open UART" << std::endl;
    }
    else
    {
      struct termios options;
      tcgetattr(uart0_filestream, amp;options);
      options.c_cflag = B115200 | CS8 | CLOCAL | CREAD;   //<Set baud rate
      options.c_iflag = IGNPAR;
      options.c_oflag = 0;
      options.c_lflag = 0;
      //options.c_line = 'n';
      //options.c_cc[VEOL] = 0; 
      tcflush(uart0_filestream, TCIFLUSH);
      tcsetattr(uart0_filestream, TCSANOW, amp;options);
    }
  }

    while(true)
    {
      memset(amp;rx_buffer[0], 0, 1024);
      int rx_length = read(uart0_filestream, (void*) rx_buffer, 1023);
      if(rx_length > 0)
      {
        rx_buffer[rx_length] = '';
        //std::string txt = std::string((char*) rx_buffer);

        for (int i = 0; i < rx_length ; i  )
        {
           ss << std::setfill('0') << std::setw(2)<< std::hex << (int)rx_buffer[i];
           //ss << std::hex << (int)rx_buffer[i];
        }
        std::string startDEL = "06";
        std::string stopDEL =  "07";

        std::string concat = std::accumulate(std::begin(ss.str()),std::end(ss.str()),std::string(""));
        std::cout << "Pulled Data : " << ss.str() << std::endl;
        std::cout << "String : " << sub_between(startDEL,stopDEL,concat) << std::endl;

      //std::cout << txt << std::endl;
      }
    }
    return 0;
  }
 

—ВЫХОД—

     Pulled Data : 42
    String : 
    Pulled Data : 426561636f6e
    String : 
    Pulled Data : 426561636f6e283229
    String : 
    Pulled Data : 426561636f6e28322920466f756e
    String : 
    Pulled Data : 426561636f6e28322920466f756e645b355d
    String : 
    Segmentation fault
 

Комментарии:

1. Вы пытались поймать сбой в отладчике, чтобы узнать, где в вашем коде это происходит? Когда произойдет сбой, каковы значения всех задействованных переменных?

2. Неопределенное поведение, stringstream::str() возвращает строку по значению, поэтому std::accumulate(std::begin(ss.str()),std::end(ss.str()) при итерации по строкам у вас есть висячие ссылки.

3. Кстати, вы хотите продолжить и добавить в поток строк ss на протяжении всего цикла чтения? Мне это кажется неправильным. Возможно, вам следовало бы определить ss в ближайшей области, прямо перед for циклом.

4. Вы accumulate выглядите как очень окольный и неэффективный способ копирования ss.str() . Какой в этом смысл?

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