-3

I don't know why this code shows Segmentation Fault.Below is the code

int main()
{   
    char *str;
    printf("\nEnter a string - \n");
    scanf("%s",str);
    printf("%s\n",str);
}

What can be the reasons for the segmentation fault? Also I would like to know why using gets()function is dangerous in Linux?

macfij
  • 3,093
  • 1
  • 19
  • 24
Nitin
  • 1
  • 3

1 Answers1

3

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.

Sagar D
  • 2,588
  • 1
  • 18
  • 31
  • 2
    Would be safer with `scanf("%39s", str);` – Basile Starynkevitch Aug 24 '14 at 12:02
  • @BasileStarynkevitch +1. But as the questioner looks like a Starter, i just introduced him to basic working :) – Sagar D Aug 24 '14 at 12:05
  • 1
    The bit about `%39s` is important because OP most likely replaced `gets` by `scanf` to get rid of the possible buffer overflow, but `scanf("%s",str)` has exactly the same vulnerability as `gets` – anatolyg Aug 24 '14 at 12:10
  • why allocate on heap ? if so, use `free(str)`, otherwise use `char str[40] = {0};` – Piotr Skotnicki Aug 24 '14 at 12:10
  • 2
    @SamDunk since he's a starter, why not start off with code that isn't horribly buggy. You say `gets` is bad but then your code does a `gets` effectively (`gets` is the same as `scanf("%s"` other than that the scanf stops on all whitespace) Also this is a good time to [not cast malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc), in 2014 there is no need to copy out of 1970s books that required this cast – M.M Aug 24 '14 at 12:32
  • also worth mentioning that `char str[40];` is a lot less effort for the same result – M.M Aug 24 '14 at 12:33
  • 1
    @MattMcNabb Sir I have made the necessary changes. Thanks for pointing out :) – Sagar D Aug 24 '14 at 12:40
  • You should of course check the return values of `malloc()` and `scanf()`. If there is no input, `scanf()` will return `0` and leave the contents of `*str` indeterminate. You're also missing declarations for all of the functions involved, which is yet another point of _undefined behaviour_. – Nisse Engström Aug 24 '14 at 13:59
  • 1
    super explanation ! – tauseef_CuriousGuy Jan 25 '19 at 13:04