If you want to do a bitwise conversion (which is what you get when you cast) then you need to use either a union or pointers. But don't expect the results to make much sense, because the internal representation of doubles is not ASCII text. If you want the conversion to result in a.x and p containing 3.1415926, then you have to use atof().
double *p=(double *)str1; //(1)
(1) Note that what I'm casting here is the pointer to "3.1415926", not the text itself, which is what you tried to do. So I'm creating p as a pointer to a double that is stored at the same location as str1 (which is why the union code does the same thing).