I saw many questions about getting segmentation fault in C program here in SO, and I thought it would be great to have a reference to those here, a question
All your examples are causing undefined behaviour, which might lead to a crash (or it might not appear to do any harm at all).
You're not allowed to change a string literal. (see e.g. here)
You forgot to allocate storage for the terminating nul byte, do malloc(strlen(str) + 1);
You're calling free() on a pointer you did not obtain from malloc (or similar functions). As you make the str pointer point to a string literal, you've lost the pointer to the memory allocated with malloc and leak memory here too.
You're calling free() twice on the same pointer, which is undefined behavior.
%s in the printf format string tells printf that the argument is a string (a char * pointing to a sequence of nul terminated characters) You're passing it a char, not a string. If you want to print the suffix of the string use printf("%s", &str[19]);
You're passing in an invalid pointer to free(), you already free'd s, you can't dereference it later when you do s->str. Reverse the order of deallocation: free(s->str); free(s);