-2

I wonder why the two values of int don't validate the if condition even if it is true. printf shows both of them are equal.

Is buffer overflow able to affect the behavior of if conditions,corrupting other code sections behavior.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h>

  int main(void) {
    srand(time(NULL));
    char instring[2]; // when this increases somehow I get the right behavior
    int inint;
    int guess;
    guess = rand() % 127;
    inint = ~guess;
    printf("%i\n", guess); //testing with printf()
    while (guess != inint) {
      printf("Guess Number\r\n");
      gets(instring);
      inint = atoi(instring);
      printf("%i\n", inint);

      if (inint > guess) {
        printf("%i\n", inint);
        puts("too high");
      } else if (guess > inint) {
        puts("too low");
      } else {
        puts("right");
      }
    }
    return 0;
  }
  • So are you really asking why a string that is too short overflows? – Weather Vane Apr 16 '18 at 05:43
  • 3
    Don't ever use `gets`! It's a dangerous function which is prone to buffer overflows (which you have) and therefore has been removed from the C specification. Use e.g. [`fgets`](http://en.cppreference.com/w/c/io/fgets) instead, or [`getline`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html) if you're on a POSIX system. – Some programmer dude Apr 16 '18 at 05:44
  • no , I said I am asking about if condition , why it does not execute , even values are equal , I'm comparing two numbers –  Apr 16 '18 at 05:44
  • As for *why* you get a buffer overflow, remember that `char` strings in C are really called ***null-terminated** byte strings*. That *null-terminator* is important, and it needs its own element in the array. Which means a string of two characters needs space for three to include the terminator. – Some programmer dude Apr 16 '18 at 05:45
  • 2
    Buffer overflow leads to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). Once you have UB then all discussion about behavior becomes irrelevant. – Some programmer dude Apr 16 '18 at 05:46
  • 1
    Your problems are caused by the buffer overflow – M.M Apr 16 '18 at 05:46
  • I uses printf to show me up the the guessed value , same time I do guess the same value and print it , and it prints correctly but if does not execute probably –  Apr 16 '18 at 05:46
  • but my conditions after getting the real values. –  Apr 16 '18 at 05:48
  • 1
    Fix the buffer overflow first. – Weather Vane Apr 16 '18 at 05:48
  • @root Is it possible that your input is UTF-16 ? So you have 2 bytes for a single character. Because of that, you miss to allocate memory for ("\0") null terminator. Since your array is 2 bytes. –  Apr 16 '18 at 05:49
  • I'm talking about two ints values conditions happens between two ints. –  Apr 16 '18 at 05:50
  • Weird things happen if you have buffer overflow. First, you need to fix that... –  Apr 16 '18 at 05:52
  • both [`atoi`](https://stackoverflow.com/q/17710018/995714) and [`gets`](https://stackoverflow.com/q/1694036/995714) shouldn't be used – phuclv Apr 16 '18 at 06:34
  • 1
    See [What are the functions from the standard library that must/should be avoided?](https://stackoverflow.com/a/46563868/584518). – Lundin Apr 16 '18 at 06:42

1 Answers1

1

The problem is indeed here.

char instring[2];

Now let's think about this line.

gets(instring);

Let's say you type 10 and hit enter. What will go into instring is three bytes.

  1. 1
  2. 0
  3. A terminating null.

instring can only hold two bytes, but gets will shove (at least) three in anyway. That extra byte will overflow into adjacent memory corrupting some other variable's memory causing some bizarre bug.

And that's why making instring large enough to hold the result from gets fixes the program.

To avoid this when working with strings, use functions which limit themselves to the memory available. In this case fgets.

fgets(instring, sizeof(instring), stdin);

That will limit itself to only reading as much as it can fit into instring.

In general, don't get stingy with memory to read input. A common practice is to allocate one large buffer for reading input, 1024 is good, and reuse that buffer just for reading input. The data is copied out of it to more appropriately sized memory, which atoi effectively does for you.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • so conditions behavior is corrupted with stack overflow ? –  Apr 16 '18 at 05:54
  • 1
    @root Not a stack overflow, that's something different, but a [buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow). Probably into `guess`. You can check their memory locations with `printf("%p / %p", &instring, &guess)`. – Schwern Apr 16 '18 at 05:56
  • Most likely the values of the int variables declared after the overflowing char array get their values changed. – o_weisman Apr 16 '18 at 05:58
  • 1
    @root Note that their order in memory isn't necessarily their order in the program. And it can change from compiler to compiler and even between compiler options. When I compile with `-fsanitize=address` `guess` comes after `instring`. But when I remove that `guess` comes *before* `instring`. Anyhow, a buffer overflow triggers [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) and all bets are off. – Schwern Apr 16 '18 at 06:02