p nie jest zainicjowana. A przecież na samym początku dałem zmienna char* p a potem wykorzystuję ją w pętli
Inicjalizacja to co innego niż deklaracja. Ty zmienną zdeklarowałeś:
char *p;
Inicjalizacja to np:
char *p = NULL;
Kompilator krzyczy, bo po deklaracji wskaźnika p wskazuje on w jakieś losowe miejsce. Nie ma tam żadnej tablicy.
Żeby zrobić to dobrze musiałbyś poczytać o dynamicznej alokacji w przypadku C funkcje: malloc, calloc, realloc i free.
Ale na szybko możesz po prostu stworzyć zwykłą tablicę 2 razy większą niż ta w mainie:
char p[200];
A tak na marginesie jeśli chodzi o samo wypisanie tego ciągu to nie musisz tworzyć nowego stringa, możesz wypisywać na bieżąco:
void echo(char* s) {
for (int i = 0; s[i] != NULL; i++) {
printf("%c%c", s[i], s[i]);
}
}
A co do mierzenia długości stringa:
while (s[len++]);
len -= 2;
to w string.h jest od tego funkcja:
int len = strlen(s);