Firstly, you may need to know that you could have used char str[40] = {0};
(compile time memory allocation).
Since you have asked a question which queries about dynamic memory allocation, you should allocate memory to a pointer before trying to store anything. Beacuse the pointer may be pointing to any random locations (wild pointer) and hence you may try to access memory which is not meant for accessing, this results in a segfault.
int main()
{
char *str;
str = malloc(sizeof(char) * 40); // allocate memory where str will be pointing,here i allocate 40 bytes
printf("\nEnter a string - \n");
scanf("%39s",str);
printf("%s\n",str);
free(str); //important to release the memory!
}
To answer your second question, gets()
is dangerous on any platform because it may cause buffer overflow.
Consider a scenario where you try to fill a buffer beyond it’s capacity :
char *buff = malloc(sizeof(char)*10);
strcpy(buff, "This String Will Definitely Overflow the Buffer Because It Is Tooo Large");
As you can see that the strcpy() function will write the complete string in the ‘buff’ but as the size of ‘buff’ is less than the size of string so the data will get written past the right boundary of array ‘buff’. Now, depending on the compiler you are using, chances are high that this will get unnoticed during compilation and would not crash during execution. The simple reason being that memory belongs to program so any buffer overflow in this memory could get unnoticed.
So in these kind of scenarios, buffer over flow quietly corrupts the neighbouring memory and if the corrupted memory is being used by the program then it can cause unexpected results.
Workaround for safety :
char *buf=NULL;
size_t siz= 30;
ssize_t len = getline(&buf,&siz,stdin);
How is this a workaround?? Well, you should read about the getline()
more.