Да, утечка памяти. Вы назначаете p для NULL перед освобождением содержимого, на которое оно указывает. Одно быстрое изменение исправит это:
int* p = malloc(sizeof(int));
free(p);
p = NULL;
Разница здесь в том, что мы освобождаем адрес, выделенный mallo c перед установкой p в NULL. В общем, установка указателя на NULL не освободит содержимое, но позволит вам проверить, является ли указатель действительным или нет, что может иметь много практических применений.