Формально, компилятор где-то запоминает, сколько он выделил памяти, и скорее всего, делает это где-то в байтах до указателя, но практически, на это полагаться нельзя.
Размер массива, аллоцированного через calloc, malloc можно узнать с помощью специальных функций, различных для каждой ОС. К примеру, для линукса этот размер можно узнать с помощью вызова malloc_usable_size. Ссылка: https://stackoverflow.com/questions/1281686/determ...
Размер второго массива узнать через sizeof(a) / sizeof(a[0]).