This code produces \"p = hello world\":
#include \"stdio.h\"
#include \"string.h\"
int main(){
char *p;
p=\"hello world\";
printf(\"p is %s \\n\",p)
Because in the first example the pointer p
contains some random garbage that happens to be on the stack at the time, might be zero, might be anything else, so it points to ... nobody knows where, your code segment, for example. The OS does the right thing and tells you that you are breaking the rules and trying to write to memory that doesn't belong to you. Read the fine description of segmentation faults here.
If you absolutely want to avoid dynamic memory allocation and you know the size of the source string at compile time you can grab appropriate stack space like this:
char buffer[6]; /* strlen( "hello" ) + 1 for zero terminator */
strcpy( buffer, "hello" );
But that is a dangerous road leading to buffer overruns.