1) Различие в том, что в в первом случае (с массивом) — память выделяется в стеке при начале работы функции и соответственно освобождается при завершении функции автоматически.
А если пользоваться malloc то эта память берется из кучи (heap). И, соответственно можно эту память без проблем передать вызывающей функции при выходе из нашей функции. Но вызывающая функция должна не забыть сделать free.
2) С классами тоже так же что и 1). Срок жизни экземпляра класса во втором случае (new) может быть больше, но зато на нас лежит ответственность — нужно не забывать вызывать delete (это аналог free, только с вызовом деструктора класса).
3) Ну а здесь по большому счету — все равно как действовать, это же наш класс (все переменные private) что захотим — то и воротим внутри, никто все равно не узнает.
Но есть такая тонкость, если мы создаем мультипоточное приложение (multithread) то нужно пользоваться мультипоточной функцией malloc (линковать с мультипоточной либой LIBCMT.LIB вместо устаревшей LIBC.LIB, для VisualStudio это флаг /MT) — иначе будут проблемы.