Переставь строки
int **ar; - неинициализированный указатель на указатель (или массив указателей) - пока НИКУДА не указывает.
переменная ar должна содержать адрес ячейки памяти, где содержится дрегой указатель, или первый элемент массива указателей, но пока содержит мусор!
Поэтому надо сначала выделить память под этот массив указателей
malloc(n*sizeof(*ar)),
присвоить адрес ее начала (адрес первого элемента в массиве) указателю ar с преобразованием типа
ar=(int**)malloc(n*sizeof(*ar));
и только потом уже выделять память для каждого элемента полученного массива
*ar=(int*)malloc(n*sizeof(int)); - этот оператор выделяет память ТОЛЬКО под первый столбец (или строку
)
на самом деле надо выделить память и под другие эдементы
for (int i=0;i<n;i++)
{
ar
=(int*)malloc(n*sizeof(int));
}
кстати, можно записать и в эквивалентной форме *(ar+i)=(int*)malloc(n*sizeof(int));
И последнее, не забудь освободить память В ОБРАТНОМ ПОРЯДКЕ!
for (int i=0;i<n;i++)
{
free(*(ar+i));
}
free(ar);