Why do we have to initialize a pointer to a string when it is declared globally ?

I mean , This doesnt work

#include<stdio.h>
#include<conio.h>

char *str;
int main(void)
{
 gets(str);
 printf("%s",str);
}

But this works

char *str="1";
int main(void)
{
 gets(str);
 printf("%s",str);
}

Even upon initializing , it gives me weird outputs
When i entered 12345 as the input string , it printed only 345. Why ??

Edited 5 Years Ago by Narue: Added code tags

Problems are not related to the variable being global. It's the size if it and whether it's null terminated or not.
read the documentation of gets() to see what it expects as the argument and what happens when user gives more chars than the size allocated for the string passed as argument.

Problems are not related to the variable being global. It's the size if it and whether it's null terminated or not.

You are right Sir, Ok, I'll look up the documentation of gets()

But can u tell me why we have to initialize with some random value when we are declaring as global. That is specific to global right ?

Thanks for the response Sir.

Neither of your programs are correct. In the first you're passing an uninitialized pointer to gets. Uninitialized pointers are not pointers to infinite memory. In the second you're passing a pointer to a string literal to gets. String literals may be placed in read-only memory, and trying to modify them (which gets does) is undefined behavior.

Finally, gets is truly evil because there's no way to make it safe from buffer overflow. Here is a correct program:

#include <stdio.h>

int main(void)
{
    char str[BUFSIZ];

    if (fgets(str, sizeof str, stdin) != NULL)
        printf("%s", str);
 
    return 0;
}

Or if you're insistent on using a pointer, it has to point to somewhere, be it an existing array or anonymous memory:

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

int main(void)
{
    char *str = malloc(BUFSIZ);

    if (fgets(str, BUFSIZ, stdin) != NULL)
        printf("%s", str);
 
    free(str); // Always free your memory

    return 0;
}

One of the nice things about fgets() is that it deals with the terminating NUL byte for you, so you know that the string is properly terminated.

As opposed to gets which also adds a terminating null character for you? :icon_rolleyes: The nice thing about fgets over gets is that it's possible to make fgets safe.

As opposed to gets which also adds a terminating null character for you? :icon_rolleyes: The nice thing about fgets over gets is that it's possible to make fgets safe.

Yes, but as you pointed out before, it may be terminated in la-la land... Many moons ago (20 or so years) I was selected to be our company's first formal software quality manager - they even sent me off for a bunch of training. So, formulating our sqa policies, my team and I started formal testing of our manufacturing cell control software. Testing for buffer overflows and remediating them was our job for quite some time. The end result? Our software was tonnes more reliable, and our customers were a LOT happier with us. With the knowledge we gained, we were able to institute formal coding practices and code reviews for all code that would make it into the production system, looking specifically for such things as this. So, all applications did things like checking input arguments for length, type, boundary values, etc.

This article has been dead for over six months. Start a new discussion instead.