-2
    #include
    int main(void)
    {
        char str[100]="88888888888888";
        char t[20]="";
        gets(t);
        puts(str);
        puts(t);
        return 0;
    }

enter image description here

The first line

555555555555555555555555555555555

is put in.

Why str is 55555555555? Why str isn't 88888888888888888 or 55555555555588888?

Mysticial
  • 464,885
  • 45
  • 335
  • 332
ytyisme
  • 29
  • 5

4 Answers4

6

You overriden the t buffer, and reached the str buffer, where the rest of the input, and the null terminator was set. And puts prints only until the null terminator.

Pretty much looks like that:

[ t (20)             ][str(100)                                 ]
 55555555555555555555  5555555555555\0

Note that although t is declared as char[20], when you print it you get the full input (longer than 20), since puts stops at the null terminator (again).

BTW, this is a buffer overflow, not a stackoverflow, but stack overflow is possible on this codeas well.

MByD
  • 135,866
  • 28
  • 264
  • 277
1

As Binyamin said it is caused by the overflow you trigger because of the input string being too long. However it is a bit random thing - sometimes the two memory allocations will happen just next to each other and the string will extend to the neighbouring variables, sometimes it might not happen.

I advise you to place guard conditions for such kind of overflows.

If you see in the gets documentation:

Notice that gets does not behave exactly as fgets does with stdin as argument: First, the ending newline character is not included with gets while with fgets it is. And second, gets does not let you specify a limit on how many characters are to be read, so you must be careful with the size of the array pointed by str to avoid buffer overflows.

In your case if you do not know the size apriory maybe it is better idea to use fgets as it is more secure (though a bit slower).

Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135
  • These two variables are going to be on the stack, not the heap - their proximity to each other will be determined at compile time (compiling in debug mode might insert padding between them, compiling with optimizations might reorder them...), so it's not something I would call *random*. – DCoder Apr 14 '12 at 15:53
  • @DCoder I don't quite get you. Once you mention that their position in the stack depends on compilation parameters. I also know that if new variables are introduced they might separate the variables. Random in the context should be read as: "depending on many circumstances, hard to predict deterministically". – Boris Strandjev Apr 14 '12 at 15:56
  • I was just trying to say that the placement is determined at compile time, not runtime, so simply running the program again wouldn't change where the allocations happen. – DCoder Apr 14 '12 at 15:59
  • @DCoder I never mentioned it will change among several runs of the same program... – Boris Strandjev Apr 14 '12 at 16:01
1

When you enter a string of more than 20 5s, it overruns the buffer that was allocated to t and extends into the buffer that was allocated to str.

Then it displays the contents of str, which is the string you entered, starting at the 21st character.

Finally, it displays the contents of t, but since that string doesn't end with a null character, it continues displaying memory (which is the buffer assiged to str) until it encounters the null character after all the 5s.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150
0

In order to avoid those allocation overlapping issues you can try this alternative, so that the allocation takes place at runtime if I'm not wrong:

    #include <iostream>

    int main(void)
    {
      char *str;
      char *t;
      str = new char(100);
      str = (char*)"88888888888888";
      t = new char(20);
      std::cin >> t;
      puts(str);
      puts(t);
      return 0;
    }
Drodbar
  • 539
  • 5
  • 14