Why does gets work even when I have not allocated memory to it?

100 views Asked by At

I recently answered a question here in SO where the problem was to input a few sentences of code and print it. My code is this:

#include<stdio.h>  

int main() {
    clrscr();
    int line, i;

    char (*string)[100];
    printf("How many line?\n");
    scanf("%d",&line);
    getchar();

    for(i=0;i<line;i++) {
        gets(string[i]);
    }

    printf("You entered:\n");
    for(i=0;i<line;i++) {
        puts(string[i]);
    }

    return 0;
}

As you see, I haven't allocated any memory to individual strings i.e, s[0],s[1] ,....... but surprisingly my compiler didn't give me any warnings or errors for it and it works perfectly.

So I posted this code and frankly got quite a few of downvotes for it (I know I deserved it). Can you please explain why this code works and not give a segmentation error?

My output is as shown:

Output

1

There are 1 answers

2
Potatoswatter On BEST ANSWER
char (*string)[100];

OK, string represents a pointer to 100 char, but it's not initialized. Therefore, it represents an arbitrary address. (Even worse, it doesn't necessarily even represent the same arbitrary address when accessed on subsequent occasions.)

gets(string[i]);

Hmm, this reads data from standard input to a block of memory starting at the random address, plus i*100, until a NUL byte is read.

Not very robust. Not guaranteed to produce an error, either. If you didn't get one, the random address must have been mapped to writable bytes.

As you see, I haven't allocated any memory to individual strings i.e, s[0],s[1] but surprisingly my compiler didn't give me any warnings or errors for it and it works perfectly.

Time to reduce your expectations, or increase the diagnostic level of the compiler. Try -Wall -Wextra, if it takes options in that style. It should be warning you that string is used without being initialized first. A warning that gets has been deprecated would also be a good idea, although my compiler doesn't mention it.

C and C++ allow you to manage memory yourself. You are responsible for validating pointers. In C, this is a major source of problems.

In C++, the solution is to use alternatives to pointers, such as references (which cannot be uninitialized) and smart pointers (which manage memory for you). Although the question is tagged C++ and compiles as a C++ program, it's not written in a style that would be called C++.