какой из вариантов наиболее эффективен / наиболее используемый
Создание класса в динамической памяти делится на 2 этапа:
1. выделение "сырой" памяти у менеджера памяти
2. инициализация памяти - вызов конструктора класса на выделенном участке памяти.
Вариант с malloc не выполняет вторую часть. Для того что бы закончить процесс в этом варианте вам надо использовать размещающий new, передав указатель на ранее выделенную память. Деструкторы так же нужно будет вызывать явно.
Если вариант с malloc довести до логического конца, то он будет делать то же самое что и вариант с new, никаких преимуществ тут нет. Но не забываем про явный вызов деструктора.
При удалении класса из динамической памяти присутствуют обратные этапы: вызов деструктора и освобождение памяти.
malloc обычно используют в плюсовом коде, когда реализуют собственные аллокаторы и нужен "сырой" не инициализированный блок памяти. Но и в этом случае вполне можно обойтись без malloc - использовать
new char[MEM_SIZE]