короче - если нужно чтобы извне контролировалось куда именно будет функция выдавать данные - например memcpy какаянибудь - тогда на вход ей нужно подавать ссылку/указатель на destination и возвращать код ошибки/ничего не возвращать, если не нужно чтобы извне контролировался выходной контейнер - тогда его можно создать внутри функции вызываемой и вернуть просто - тогда функция ссылок/указателей на контейнер не принимает, но возвращает уже контейнер. Если нет весомых причин использовать первый вариант - лучше по дефолту использовать второй, для вызова функции дополнительных телодвижений и условий не требуется, она сама все внутри сделает и вернет результат