According to my textbook,
char *p = "hello";
- A pointer to a string where both the string and the pointer can be modified
const char *p = "hello";
- A pointer to a constant string where the string cannot be manipulated but the pointer can be manipulated to point to another char string
char *const p = "hello";
- A constant pointer to a string where the string can be manipulated but the pointer cannot be manipulated to point to another char string
- const char *const p = "hello";
- both the string or the pointer cannot be changed.
But here are my output for the different cases when the string can be modified -
#include <stdio.h>
int main() {
// Write C code here
char *p = "hello";
*p = 'a';
//p = "bye";
printf("%s",p);
return 0;
}
Output : Segmentation Fault
#include <stdio.h>
int main() {
// Write C code here
char *const p = "hello";
*p = 'a';
//p = "bye";
printf("%s",p);
return 0;
}
Output: Segmentation Fault
When do I get a segmentation fault in these cases when almost all the references I came across says otherwise? Thanks.

Though in C opposite to C++ string literals have types of non-constant character arrays nevertheless you may not change a string literal. Any attempt to change a string literal results in undefined behavior.
From the C17 Stndard (6.4.5 String literals)
Sp it is better in C to declare pointers to string literals with the qualifier
constas for exampleIf a pointer (without the qualifier
const) points to a non-constant array then you may change the array using the pointer. For exampleSo it will be better and correct to rewrite all your examples using an intermediate array as shown above. For example