Programming is the art of finding good compromises. Dynamically allocated memory can have a certain place, and I can even think of problems where a good compromise between code complexity and efficiency is achieved with std::vector<std::vector<T>*> .
However, std::vector does just fine with most of the needs of dynamically allocated arrays, and managed pointers are many times just the perfect solution for dynamically allocated single instances. This means that this is not so common when detecting cases where an unmanaged dynamically distributed container (or actually dynamically distributed) is the best compromise in C ++.
This, in my opinion, does not make the dynamic distribution βbadβ, but simply βsuspiciousβ if you see it in the code, because there is a high probability that better solutions may be possible.
In your case, for example, I see no reason to use dynamic allocation; just a function returning std :: vector would be efficient and safe. With any decent compiler, Return Value Optimization will be used when assigning to a just declared vector, and if you need to assign a result to an existing vector, you can still do something like:
FindPoints().swap(myvector);
which will not do any copying of the data, but simply hide the pointer (note that you cannot use the obviously more natural myvector.swap(FindPoints()) due to the C ++ rule, which is sometimes annoying, which prevents the transfer of temporary data as non-constant links).
In my experience, the biggest source of the needs of dynamically allocated objects are complex data structures in which the same instance can be reached using several access paths (for example, instances are both in a doubly linked list and indexed on a map), The standard library containers are always the only owner of the contained objects (C ++ - semantic language copies), so it may be difficult to implement these decisions effectively without indicator concept and din nomic allocation.
Often you can make enough reasonable tradeoffs that just use standard containers (maybe paying extra O (log N) requests that you could avoid), and that, given the much simpler code, IMO might be the best tradeoff in most cases .