Gadasz jakieś bzdury. Program wcale nie przerywa działania, o ile oczywiście przekazujesz jako argument C-stringa a nie tablicę znaków (tzn na koncu stringa masz znak '\0') i nie przekazujesz tam jakiegoś stałego napisu.
Poza tym z tego co piszesz wynika że zupełnie nie rozumiesz tego kodu.
Przypisanie
*q = *p
Znaczy tyle co: do pamięci na którą pokazuje wskaźnik q przypisz wartość na którą pokazuje wskaźnik p.
Początkowo p wskazuje na początek, q na koniec i potem sie do siebie zbliżają. Oczywiscie to nie odwróci ci stringa tylko przerobi go na śmieszny palindrom. Żeby odwrócic stringa musiałbyś napisać
char tmp = *q;
*q = *p;
*p = tmp;
Poza tym twój "przykładowy kod" woła o pomstę do nieba.
char* to WSKAŹNIK do pokazywania na char. Żadna tablica! Co więcej NIE WOLNO ci nic wpisać pod ten wskaźnik, bo nie wiesz gdzie on pokazuje. Że akurat ci to zadziałało to twoje szczęście, równie dobrze mógł polecieć segfault (i powinien...). Żeby przypisać coś pod wskaźnik musisz zaalokować pamięć (malloc() lub new).
Zresztą nic wspólnego nie ma to z kodem który podałeś, bo w twoim kodzie wskaźniki poruszają sie po twojej pamięci (bo poruszają sie po tablicy char).
Nie pokazałeś tego co istotne ale zgaduje że zrobiłeś coś takiego:
odwroc("ala ma kota");
I to faktycznie spowoduje wysypanie sie programu. Czemu? Bo napis "ala ma kota" znaduje sie w obszarze pamięci której nie wolno ci modyfikować i próba modyfikacji powoduje błąd (ale gcc pozwala kompilować program tak zeby takie napisy dało sie modyfikować). Czemu nie wolno tego modyfikować?
Bo kompilator moze sobie to tak poustawiać że masz np. napis
"ala ma kota"
i napis
"ala"
I zostanie to tak zrobione że w pamięci fizycznie będzie tylko napis "ala ma kota" (bo napis "ala" będzie po prostu odczytywany z tego samego miejsca w pamieci).
edit: tak jak myślałem wysyłasz do funkcji STAŁY napis, którego nie wolno ci modyfikować. Takie wywołanie:
char zmienna[]="ala ma kota";
odwroc(zmienna);
Wyeliminuje problem wysypywanie się programu, bo po tej pamieci wolno ci pisac.