-3

I have a piece of code that is supposed to flush an array of characters when the enter key is pressed, only the code is looping infinitely and I can't figure out why.

There is a character array that gets a new character every time a key is pressed. When the enter key is detected, the following code gets executed to flush the character array with '\0' characters before generating a new line on the screen:

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++;
            }
        }
}

The i gets incremented in the main loop every time a character gets pressed (other than an enter (ASCII 13)). The character is also added to buffer[]. That code is not shown here, though I can reproduce it. Needless to say, even if that code were improperly incrementing the i, the loop should end when i hits 0 (and i should hit 0 at some point given the decrement).

So in theory, on having an enter pressed, if there are 5 characters on the line (and no backspaces), buffer[] elements 0-4 will have the characters, and i will be equal to 5. The loop in the code should replace elements 5 to 0 with '\0' characters. Starting with element 5 is admittedly unnecessary, but it shouldn't cause the behavior I've been experiencing.

That behavior is that the loop runs endlessly. Right now I've been able to verify this by using my putchar function to print a character every time the loop is run. Now I suppose I could write another function to enable me to print the value of i as well, and I would probably obtain the answer to my question. Also, for what it's worth, the infinite loop happens when I turn this loop into the equivalent "while" loop.

I just wanted to make sure there isn't something obvious that would be causing infinite loop behavior here. Sorry if this is a stupid question. Thanks for any help. The program is being run as a raw binary in 16 bit real mode. I'm compiling from bcc to as86 to the final binary.

Edit: After doing some more debugging, I confirmed that i is going into the loop with the correct positive value (based on the number of characters in the array, e.g., i = 7 if 7 characters). While in the for loop, however, i alternates between a value of -1 and -2 ad infinitum. Since that makes no sense based on i's entry value (or based on the loop's condition), is there any chance this is some kind of memory or register issue?

Final edit: the issue appears to have been the >= condition causing i to go negative. For some reason, this caused an infinite loop even though the condition in the for loop checks for a negative i. Thanks for all of the help.

Learning
  • 35
  • 6
  • 2
    The enter key is usually translated to `'\n'`, a.k.a. the newline, for text streams, which usually has value 10, not 13... – Antti Haapala -- Слава Україні Feb 09 '20 at 18:51
  • I can confirm that 13 is correct here; I've run the code many times without this particular troublesome loop and enter is processed as ascii 13. When I use '\n,' it does not work. Thanks though; I appreciate the response. – Learning Feb 09 '20 at 18:53
  • 1
    I don't see where you have reset `i` between the `while` and `for` loops. – Weather Vane Feb 09 '20 at 18:54
  • "_the loop should end when i hits 0_" - actually it ends when it becomes _less than_ zero. That will only happen if it is _signed_ and you have not included its declaration. – Clifford Feb 09 '20 at 18:54
  • Then the problem is in some other part. There is hardly enough code for a [mre] here. – Antti Haapala -- Слава Україні Feb 09 '20 at 18:54
  • Even your antique BCC compiler comes with a debugger - that is a far more effective technique that posting questions of SO. Better to ask a question about how to use the debugger effectively than to ask about a single bug. – Clifford Feb 09 '20 at 18:57
  • I just added some more code. If I can provide any more information, please let me know. Thanks for the responses. Also, I tried changing the variable explicitly to a signed char and it did not fix the infinite loop problem. And I'm looking at bcc's debugger now. – Learning Feb 09 '20 at 19:12
  • Are you sure `bcc` has char = signed char? If it's `unsigned char`, then `i>=0` is always true. – Peter Cordes Feb 09 '20 at 20:49
  • @PeterCordes I tested it explicitly making i a signed char, and it didn't change the result unfortunately. – Learning Feb 09 '20 at 21:02

1 Answers1

2

For some reason, this caused an infinite loop even though the condition in the for loop checks for a negative i.

"the condition in the for loop checks" is true, yet the condition is not checked everywhere it is needed.


At least one problem: attempting buffer[-1] = c; which is undefined behavior (UB) - which can include an infinite loop.

When the input after (c == 13) is not 13, code attempts this 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--) is questionable as its first buffer[i] = '\0'; is on something that was not set in the else's buffer[i] = c; i++; part.

I suspect OP needs

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

char i; is unusual. I'd expect a fixed signed type, not a char which might be signed or unsigned. Perhaps unsigned char i (after above fix) or an idiomatic size_t i; for array indexing.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thanks. This did fix the problem. I don't understand how the UB problem could be attributable to assigning c to buffer[-1], however. When the program was run, there was absolutely no input *after* the 13 (enter press). Once the enter press happened, the program went into an infinite loop and would accept no further input. So there would have been no way for the else branch to have ever assigned c to buffer[-1]. – Learning Feb 10 '20 at 00:44
  • 1
    @Learning ... or "there was absolutely no input after the 13 (enter press)" is not so. Without code showing how that was determined, we are left to speculation as to the reported findings. AFAIK, an caused 13, 10. I do not know how long the input was. The code posted is not your true code. So many possibilities. Review [MCVE]. – chux - Reinstate Monica Feb 10 '20 at 04:32