Ошибка сегментации при попытке прочитать, пока заголовок не встречается в C - PullRequest
1 голос
/ 02 июля 2011

Я новичок в C, так что извините за простоту вопроса. Я пытаюсь написать функцию (как библиотеку, поэтому она должна быть надежной), которая постоянно читает один байт (EDIT: из последовательного порта), пока не встретится начальный байт заголовка. Если он найдет его, он прочтет остальную часть заголовка и полезную нагрузку и сохранит его в структуре. Начало моего кода выглядит примерно так (будет добавлен псевдокод):

soh_read = 0;
bytes_read = 0;
bytes_left = 1;

do{
    n = read(fd, buf + bytes_read, bytes_left);
    if(n < 0){
        if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR){
            return -1;
        }
    }else{
        bytes_read += n;
        if(!soh_read){
            if(buf[0] != SOH){
                bytes_read = 0;
                continue;
            }
        }
        soh_read = 1;
        //read header ...
        //read payload ...

}while(timeout is not reached);

Я предположил, что мог бы сбросить bytes_read на 0, если SOH не обнаружен, и попытаться снова прочитать в позиции buf [0], перезаписывая ранее прочитанный мусор. Но похоже, что это случай переполнения буфера и почему я получаю ошибку сегментации? Почему это не сработает? Если так, каков наилучший способ сделать это? Я хотел начать с buf [0], чтобы было легко отслеживать каждое из полей сообщения. Просто пытаюсь поучиться у экспертов здесь, спасибо.

1 Ответ

4 голосов
/ 02 июля 2011

Вы пропустили некоторую информацию, необходимую для диагностики проблемы с вашим кодом в его нынешнем виде.Самым важным является (вероятно) то, что ваш SOH может появиться позже в файле, чем вы дали место в вашем buf.

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

do { 
    read(fd, buf, 1);
    if (n<0 && errno != EWOULDBLOCK && /* ... */)
       return -1;
} while (buf[0] != SOH and !timeout_reached);

// read the header here
...