-1

I have created this simple program that takes input from 3 employees. First, it asks for the size of the employee's id. Then it dynamically allocates the size to a character array. Suppose I give the size 4 to the array. Here, I understand we can enter 3 characters as the last one would be '\0'. However, during runtime, I can enter characters more than I initially assumed it would allow to. Why is this happening? Is it expected to get an error?

Code:

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

int main()
{
    int input;
    char *ptr;

    for (int i = 1; i <= 3; i++)
    {
        printf("\nEmployee %d\n", i);
        printf("    Enter the number of characters in your eID: ");
        scanf("%d", &input);

        ptr = (char *)malloc((input + 1) * sizeof(char));

        printf("    Enter your eID: ");
        scanf("%s", ptr);

        printf("    Employee eID entered: %s", ptr);

        free(ptr);
    }

    return 0;
}

Output:

Employee 1
    Enter the number of characters in your eID: 4
    Enter your eID: 12345
    Employee eID entered: 12345
Employee 2
    Enter the number of characters in your eID: 3
    Enter your eID: 1234
    Employee eID entered: 1234
Employee 3
    Enter the number of characters in your eID: 2
    Enter your eID: 123
    Employee eID entered: 123
  • It is not expected that you will get an error message. It *is* expected that strange things will happen -- if not now, then eventually. It is a true fact that it's wrong to write more to a malloc'ed region than was specified as its size. If you don't get an immediate error message or failure, that doesn't mean the true fact somehow isn't true. – Steve Summit Jul 06 '21 at 15:20
  • overruning the size of a buffer is one of the many ways in C to invoke [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior). The behavior is undefined, meaning everything could appear to work correctly, it might manifest in a segfault, it might exhibit strange behavior some time later, it might work for you now but not on another machine or with different compiler flags. The aim is to write well defined programs, not try to understand or explain the behavior of UB in your particular instance. – yano Jul 06 '21 at 15:24
  • FYI, this is a comprehensive (although probably not exhaustive) list of ways to invoke UB in C ... overrunning a memory buffer as you have here comes in at #14: https://www.wikiod.com/w/C_Undefined_behavior – yano Jul 06 '21 at 15:27

1 Answers1

0

Questions like this get asked a lot. I'm not sure, but I think the motivation behind asking the question goes something like this.

  1. I heard that if you allocate 5 bytes, it's wrong to write more than 5 bytes to that memory.
  2. But I tried it, and I didn't get an error message, and nothing went wrong -- it seemed to work.
  3. So maybe I misunderstood when someone said I couldn't do it. Maybe, when I write more than 5 bytes, it's automatically reallocating somehow.

Now, the truth is that:

  1. #1 is absolutely true. If you allocate 5 bytes, it is definitely wrong to write more than 5 bytes to that memory.
  2. #2 happens all the time. Sometimes, if you write more than you were supposed to, it seems to work.
  3. #3 is a completely false conclusion. The fact that it seemed to work does not mean it was okay, after all. (And there is certainly not any automatic reallocation going on anywhere!)

We've used all sorts of analogies over the years to try to explain this sort of thing. One of the oldest, quipped by someone named Roger Miller on the Usenet newsgroup comp.lang.c back in the day, and still mentioned in the C FAQ list, is, "Somebody told me that in basketball you can't hold the ball and run. I got a basketball and tried it and it worked just fine. He obviously didn't understand basketball."

Another popular one is "I heard you're not supposed to go through the intersection when the light is red [or when the sign says DON'T WALK]. But I tried it last night, and nothing bad happened."

In the case of writing more to an array (or malloc'ed region) than it was defined to hold, another analogy I've used is "I bought a 40 by 40 foot plot of land. But then I built a 50 foot long house on it, such that it went 10 feet outside my property. No giant error message 'property line exceeded' appeared in the sky, so I guess it was okay." [1, 2]

Steve Summit
  • 45,437
  • 7
  • 70
  • 103