Tylko wiesz co, to jest taki sobie pretekst do użycia tablic dynamicznych. Przecież wiesz jak długa będzie liczba konwertowana. Jeśli w Twoim systemie int ma 32 bity (a jak wiadomo najmniej może mieć 16), to będzie to 8 bajtów czyli 8 pozycji hex. No ale załóżmy że się upierasz. To sprawa jest prosta.
// Będzie "na piechotę" dla zrozumienia..
// Określenie wielkości int'a
size_t intSize = sizeof(int);
// + 1 bo będziesz chciała zapisać znak \0 kończący c-string
// Od razu zerujemy tablicę poprzez użycie ()
char * hexResult = new char[intSize + 1]();
// ... tu jakieś użycie tej tablicy...
// Na koniec sprzątanie
delete hexResult;
Tylko to podejście generuje łatwo potencjalne błędy (zapomnisz sprzątnąć, pomylisz się itp... ). Lepiej użyć dedykowanego kontenera. To może być vector który robi to wszystko sam tylko... będziesz parsowała dane od ostatniego znaku hex a push_back() na vector odkłada je na końcu. Tak więc po parsowaniu, należy zawartość vector obrócić. Zrobisz z użyciem std::reverse(...) z <algorithm>. A nie ma innego kontenera który ma push_front(...)? No pewnie że jest!
Kontenerem który posiada push_front(...) jest np. std::list. Możesz dodawać znaki z jego użyciem na początku.
Co do rozwiązań z kontenerami, oczywiście są "ciężkie". Nie ma jednak sensu optymalizować na etapie ćwiczeń i zapoznawania się z kontenerami (do czego pretekst tu może być). Można np. dokonać konwersji dec->hex szybko z użyciem masek bitowych. Ale tu nie chodzi o "ściganie" :-)