Для l oop через массив вызывая бесконечный цикл - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть фрагмент кода, который должен вызывать sh массив символов при нажатии клавиши ввода, только код бесконечно зацикливается, и я не могу понять, почему.

Там массив символов, который получает новый символ при каждом нажатии клавиши Когда клавиша ввода обнаружена, следующий код выполняется для flu sh массива символов с символами '\ 0' перед генерацией новой строки на экране:

int main()
{
    char i;
    char c;
    char buffer[80];
    i = 0;
    c = 0;

        while (c = bgetchar())
        {
            if (c == 13)
            {
                for (i = i; i >= 0; i--)
                {
                    buffer[i] = '\0';
                }
            }
            else
            {
                buffer[i] = c;
                i++;
            }
        }
}

Значение i увеличивается в main l oop каждый раз, когда нажимается символ (кроме ввода (ASCII 13)). Символ также добавляется в буфер []. Этот код здесь не показан, хотя я могу его воспроизвести. Само собой разумеется, что даже если этот код неправильно увеличивал значение i, значение l oop должно заканчиваться, когда i достигает 0 (и я должен достигать 0 в некоторый момент, учитывая уменьшение).

Итак, теоретически, на при нажатой клавише ввода, если в строке 5 символов (и нет пробелов), элементы 0-4 буфера будут содержать символы, и я буду равен 5. Символ l oop в коде должен заменить элементы От 5 до 0 с символами '\ 0'. Начать с элемента 5, по общему признанию, нет необходимости, но это не должно вызывать поведение, которое я испытываю.

Такое поведение таково, что l oop работает бесконечно. Прямо сейчас я смог проверить это, используя функцию putchar для печати символа каждый раз, когда запускается l oop. Теперь я полагаю, что мог бы написать еще одну функцию, которая позволила бы мне также вывести значение i, и я, вероятно, получил бы ответ на свой вопрос. Кроме того, что бы это ни стоило, бесконечное l oop происходит, когда я превращаю это l oop в эквивалентное "while" l oop.

Я просто хотел убедиться, что ничего нет Очевидно, что это будет вызывать бесконечное поведение l oop здесь. Извините, если это глупый вопрос. Спасибо за любую помощь. Программа запускается как двоичный файл в 16-битном реальном режиме. Я компилирую от b cc до as86 до финального двоичного файла.

Редактировать: После некоторой дополнительной отладки я подтвердил, что я перехожу к l oop с правильным положительным значением (в зависимости от количества символов в массиве, например, i = 7, если 7 символов) ). Однако в течение для l oop я чередую значение от -1 до -2 до бесконечности. Поскольку это не имеет смысла, основываясь на значении записи i (или на условии l oop), есть ли вероятность, что это какая-то проблема с памятью или регистром?

Окончательное редактирование: проблема, по-видимому, связана с условием> =, из-за которого значение i равно go. По какой-то причине это вызвало бесконечность l oop, хотя условие в for l oop проверяет наличие отрицательного значения i. Спасибо за помощь.

1 Ответ

2 голосов
/ 10 февраля 2020

По какой-то причине это вызвало бесконечное l oop, хотя условие в for l oop проверяет отрицательное значение i.

"условие в for l oop проверяет "верно, но условие не проверяется везде, где оно необходимо.


По крайней мере, одна проблема: попытка buffer[-1] = c;, что неопределенное поведение (UB ) - который может включать в себя бесконечное l oop.

Когда вход после (c == 13) не равен 13, код пытается это UB.

    while (c = bgetchar()) {
      if (c == 13) {
        for (i = i; i >= 0; i--) {
          buffer[i] = '\0';
        }
        // now i == -1;
      } else {
        // No protection here that `i` is on the 0..79 range
        buffer[i] = c;
        i++;
      }
    }

for (i = i; i >= 0; i--) сомнителен, поскольку его первый buffer[i] = '\0'; находится на чем-то, что не было установлено в чужой buffer[i] = c; i++; части.

Я подозреваю, что OP нуждается

        // for (i = i; i >= 0; i--) {
        for (i = i; i > 0; ) {
          // buffer[i] = '\0';
          buffer[--i] = '\0';
        }

char i; необычно. Я ожидаю фиксированный тип со знаком, а не char, который может быть подписанным или без знака. Возможно unsigned char i (после вышеуказанного исправления) или идиоматический c size_t i; для индексации массива.

...