4

This is a practice question from my school, it's not a homework question:

Given the following declaration, write a snippet of C code that might lead to strlen(arr) returning no less than 8.

char arr[4];

My attempt to this question is: impossible, there is no way to achieve this. Since strlen will return the number of chars in an char array until it meets the first \0, I don't see there is anyway we can let strlen return 8 in this case. I think if we force to assign a 8-length-long string to this array, the behavior is not predictable.

However, the solution that our instructor gives is the:

strcpy(arr, Any 8-char-long string);

For example:

strcpy(arr, "Overflow");

I don't understand why this is valid, in my understanding, I don't see this array has enough space to hold this 8-length string, is there something I miss for understanding the string in C?

Mailerdaimon
  • 6,003
  • 3
  • 35
  • 46
DigitalSoul
  • 139
  • 1
  • 8
  • If you have `strcpy(arr, "Overflow");`, then a buffer overflow occurs and bytes after the `arr` array are overwritten. Depending on what is overwritten, `strlen(arr)` might then return 8, but as writing beyond the bounds of an array is undefined behaviour, other things may happen as well. Also read this: https://stackoverflow.com/q/15646973 – Jabberwocky Apr 25 '19 at 06:44
  • It's *not* valid to copy an 8-char-long string into a 4 char array. But (I think) that's the point your instructor is trying to make . The compiler won't stop you from doing that. And the runtime may or may not stop you from doing that. So you need to be very careful that the destination array is big enough to hold any string that you copy into it. BTW, the longest string you can copy into `arr[4]` is a 3 byte string, e.g. `strcpy(arr, "abc")`. The fourth byte in the array is needed for the `\0` terminator. – user3386109 Apr 25 '19 at 06:45
  • 1
    Yes I feel weird too, as undefined behavior should be the answer I think. – DigitalSoul Apr 25 '19 at 06:46
  • The wording "might" is key in the question asked. Yes, it is possible to copy 9 or more characters into a 4-character array, `arr`. Yes, the behaviour on doing so is undefined. But it also *might* cause a subsequent call `strlen(arr)` to return 8 or more - since that is within the realm of possibility when behaviour is undefined. It *might* also do something completely different. There is plenty of production code with undefined behaviour that, to the best knowledge of anyone, actually behaves in a manner deemed "valid" (whatever that is.....). – Peter Apr 25 '19 at 07:08
  • 1
    Well, just to be contrarian, you could put that **char arr[4]** in a **union** with a larger, say, **char bigstring[999]**. And now you can legally solve the problem, without overflow. But that's maybe trickier than the instructor was thinking. Anyway, assuming _"Your instructor is incompetent"_, as per Lundin's answer, you can point out this tricky solution at the same time you're finding a nicer (much nicer) way to call him (or her) incompetent:) – John Forkosh Apr 25 '19 at 08:41

1 Answers1

3

"Given the following declaration, write a snippet of C code that might lead to strlen(arr) returning no less than 8."

That is not possible, since arr can only hold 3 characters and 1 null terminator.

My attempt to this question is: impossible, there is no way to achieve this

Correct.

However, the solution that our instructor gives is the: strcpy(arr, Any 8-char-long string);

Your instructor is incompetent and shouldn't be teaching C. This will write out of bounds of the array and anything can happen, including program crashes or the program seeming to work as intended this time of execution.

I don't understand why this is valid

It is not, it invokes undefined behavior.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 5
    And that clearly was the whole point. They aren’t incompetent. They didn’t say “*will lead to*”, they said “*might lead to*” and they are correct. So it is entirely possible, even if it is undefined behavior. You can’t say this would never happen because it is *undefined*. – Sami Kuhmonen Apr 25 '19 at 06:51
  • @SamiKuhmonen But that's a stupid assignment no matter. If I write the C code `1 / 0;` then it might too lead to strlen returning 8, since it is also undefined behavior. Teaching students to expect a certain behavior where none is to be expected is bad. – Lundin Apr 25 '19 at 06:53
  • 3
    I can’t in any way read the given assignment as telling them “expect this to return 8.” This combined with explanation what’s happening is a good thing. Assuming it is explained. It will clearly show the main point: things that *seem* to work don’t always work, so don’t trust “*it worked at first*” etc. I would call that competent teaching. But only if it is actually explained properly which we don’t know. And as we know this specific example is very probably returning 8, your 1/0 most likely wouldn’t. – Sami Kuhmonen Apr 25 '19 at 06:58
  • @SamiKuhmonen The problem with reasoning like that is that next up someone will write code such as `do { strcpy(arr, "Overflow"); } while(strlen(arr)<8);` and expect it to behave predictably. – Lundin Apr 25 '19 at 07:00
  • 2
    Then they will write it regardless of the teaching. They clearly aren’t listening and/or understanding. That has been shown time and time again. – Sami Kuhmonen Apr 25 '19 at 07:01