-1

I have a code

char s[5];
cin >> s;
cout << strlen(s);
cout << endl;
cout << s;

It works even if I input more than 5 chars, for example "qwertyui". Does it mean that I am using not allocated memory?

Pavel
  • 5,374
  • 4
  • 30
  • 55

2 Answers2

2
strlen(s)

is something, but has nothing to do with 5. strlen applies to C strings, which are char arrays, but their length is defined as the numbers of characters until the first zero byte happens.

Now, cin in your second line cannot know how long your char[] is, so it just accepts as much input as there is. You must never use char buffers for input you don't know is well-formed. What you're seeing is a buffer overflow in action. Writing over memory that doesn't belong to any variable you allocated results in undefined behaviour, so your program might just work, crash with e.g. a segfault (accessing memory that the OS never gave you), or overwriting existing part's of your processes' memory, or … just do anything, because it's really undefined.

So, you're writing C++, not C. just

string s;
cin >> s;
cout << s.length()
<< endl
<< s;

to avoid dealing with the (very dangerous) C strings.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • Thank you, I'm just doing my homework where I can't use . I know that strlen(s) is searching '\0'. Is it any easy way to control overflow via 'cin', or I must input it char by char via 'for' and 'getchar()'? – Pavel Apr 09 '16 at 13:59
  • @Pavel: what you can and cannot use **must be in your question**. Please update your question. – Marcus Müller Apr 09 '16 at 14:33
0

You're right, it might still echo correctly if you write more than 5 characters. You're simply writing off the end of the buffer, and just blasting the memory that's next to the memory allocated for char s[5]. This is bad for many reasons, including security vulnerabilities. See here for details.

If you can't use string (for whatever reason), use fgets. See here for the documentation on fgets and how it is used. NEVER USE gets. It's almost equivalent to what you've done above, see here for why gets is so dangerous.

Community
  • 1
  • 1
Matt Messersmith
  • 12,939
  • 6
  • 51
  • 52
  • Thanks, can you tell how to avoid such blasting the memory? – Pavel Apr 09 '16 at 14:02
  • If you're in C++, I recommend doing what Marcus Muller has suggested. If you're in C land, you can use `fgets` which takes an argument that assures your input can only be so long. If the input is longer, it will only read the number of bytes you specify, and no more. – Matt Messersmith Apr 09 '16 at 14:05
  • Thank you, it's what I need – Pavel Apr 09 '16 at 14:08
  • Great! Glad to help. I'd change the tag of the question to C instead of C++ if that's the case. Despite their similarities, they are also different :). – Matt Messersmith Apr 09 '16 at 14:10
  • I'm using C++ but I can't use because it's the homework and I can use only concrect libs. – Pavel Apr 09 '16 at 14:34
  • If your homework is to write C++, then fgets is *not* the answer. It's a C relict, that's in C++ for compatibity reasons only. – Marcus Müller Apr 09 '16 at 16:45
  • Not being able to use `` but `` is OK? That is kind of contradicting itself. They are part of the same library, the C++ standard library. – Marcus Müller Apr 09 '16 at 16:47