Naik, 1. Не совсем понял, что ты там про указатели имел в виду, но, по-моему там ошибка во внутреннем цикле - нужно sizeof(**arr), то есть одной ячейки, а sizeof(*arr) - это размер всей строки.
Нам нужно выделить память под двумерный массив структуры. Одна запись структуры в памяти будет занимать грубо говоря sizeof(Cell) = sizeof(cost) + sizeof(items) = 2 * sizeof(int) = 4..32 байта (в зависимости от платформы). Пусть будет 16, как для 32битных систем.
Чтобы создать массив из col элементов структуры, нам потребуется sizeof(arr[]) = col * sizeof(Cell) = col * 2 * sizeof(int) байт, то есть col * 16.
Чтобы создать двумерный массив row x col, нужно sizeof(arr[][]) = row * sizeof(arr[]) = row * col * sizeof(Cell) = row * col * 2 * sizeof(int) байт. То есть row * col * 16 байт.
Даже если ты будешь хранить указатели на row одномерных массивов arr, тебе всё равно нужно row раз выделять память под одномерный массив. Собственно, по-сути это и делается.
Надеюсь, понятно объяснил?
2. Я не знаю, что делает free? Если это аналог delete [] arr в C++, тогда нет. Сначала освобождай каждую строку массива, а потом сам массив. Получается обратная операция той, что была в первом случае.
for(int i = 0; i < row; i++) free(arr[i])
free(arr);
Сначала освобождаем данные в arr[0][0..col], arr[1][0..col], а потом освобождаем указатели на строки arr[0..row][].
__________________