Проблем по нахождению последнего отрицательного элемента и удалению нулей нету.


for(int i = 0; i < n; ++i) Считать чётные элементы надо, то есть надо изменять переменную countEven: ++countEven % 2 == 0 Считать надо чётные элементы, то есть проверять чётность надо до проверки количества чётных: (arr[i] % 2 == 0 && ++countEven % 2 == 0) Но основной недостаток кода в том, что постоянно перевыделяется память и перемещаются одни и те же элементы. При этом получается квадратичная сложность. int countToInsert = 0;
int countEven = 0;
for(int i = 0; i < n; ++i)
if(arr[i] % 2 == 0 && ++countEven % 2 == 0) ++countToInsert;
int n2 = n + countToInsert;
arr = realloc(arr, n2 * sizeof(*arr));
for(int i = n - 1; i >= 0; --i) {
arr[i + countToInsert] = arr[i];
if(arr[i] % 2 == 0 && countEven-- % 2 == 0) arr[i + --countToInsert] = lastNegative;
}
n = n2; Тогда перед 6 должна стоять -7