2

I am writing a C program, which has a 5-element array to store a string. And I am using gets() to get input. When I typed in more than 5 characters and then output the string, it just gave me all the characters I typed in. I know the string is terminated by a \0 so even I exceeded my array, it will still output the whole thing.

But what I am curious is where exactly gets() stores input, either buffer or just directly goes to my array?
What if I type in a long long string, will gets() try to store characters in the memories that should not be touched? Would it gives me a segment fault?

haccks
  • 104,019
  • 25
  • 176
  • 264
  • As far as C is concerned, a long string in a short buffer results in "undefined behavior". There's no telling what exactly what will happen. In practice, though, the behavior will almost always involve data corruption and/or segfaults. – cHao Jan 11 '14 at 22:14
  • Welcome to stack overflow. As this is your first question, I would suggest you to read [about page](http://stackoverflow.com/tour) first. – haccks Jan 11 '14 at 22:38
  • Possible duplicate of [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – phuclv Aug 08 '18 at 15:05

4 Answers4

6

That's why gets is an evil. It does not check array bound and often invokes undefined behavior. Never use gets, instead you can use fgets.
By the way, now gets is no longer be a part of C. It has been removed in C11 standard in favor of a new safe alternative, gets_s1 (see the wiki). So, better to forget about gets.


1. C11: K.3.5.4.1 The gets_s function

Synopsis

#define _ _STDC_WANT_LIB_EXT1_ _ 1
#include <stdio.h>
char *gets_s(char *s, rsize_t n);
haccks
  • 104,019
  • 25
  • 176
  • 264
  • I think from memory the appendix K stuff is optional. For true portability, you're probably better off with fgets. – paxdiablo Apr 19 '14 at 09:22
0

gets() will store the characters in the 5-element buffer. If you type in more than 4 characters, the end of string character will be missed and the result may not work well in any string operations in your program.

unxnut
  • 8,509
  • 3
  • 27
  • 41
0

excerpt from man page on Ubuntu Linux

   gets() reads a line from stdin into the buffer pointed to  by  s  until
   either a terminating newline or EOF, which it replaces with a null byte
   ('\0').  No check for buffer overrun is performed

The string is stored in the buffer and if it is too long it is stored in contiguous memory after the buffer. This can lead to unintended writing over of data or a SEGV fault or other problems. It is a security issue as it can be used to inject code into programs.

Vorsprung
  • 32,923
  • 5
  • 39
  • 63
0

gets() stores the characters you type directly into your array and you can safely use/modify them. But indeed, as haccks and unxnut correctly state, gets doesn't care about the size of the array you give it to store its chars in, and when you type more characters than the array has space for you might eventually get a segmentation fault or some other weird results.

Just for the sake of completeness, gets() reads from a buffered file called stdin which contains the chars you typed. More specifically, it takes the chars until it reaches a newline. That newline too is put into your array and next the '\0' terminator. You should, as haccks says, use fgets which is very much alike:

char buf[100];              // the input buffer
fgets(buf, 100, stdin);     // reads until it finds a newline (your enter) but never
                            // more than 99 chars, using the last char for the '\0'
// you can now use and modify buf
DiscobarMolokai
  • 544
  • 2
  • 6
  • 20
  • @haccks Why? I don't do that all too often now, but I remember writing my first C programs; they required input being typed at various points. Then fflush was invaluable, because without it 'old' characters interfered with subsequent reading... especially with getchar() and I really had trouble finding out why. I assumed the OP is quite new to C and I just thought my 'rule of thumb' could be helpful. – DiscobarMolokai Jan 11 '14 at 22:43
  • @DiscobarMolokai `fflush` only has defined behaviour for output streams. Some implementations have specific extensions that allows `fflush` on input streams, but neither you nor the OP gives any indication of the implementation, so there's no way of telling whether that extension is applicable. –  Jan 11 '14 at 23:26
  • @hvd And yet again I learn something. I'll remove it from the answer. – DiscobarMolokai Jan 12 '14 at 10:33