I have used object pools combined with linked lists for this kind of thing in the past. Provided you don't need random access to a projectile it should work just fine.
Pool allocates and stores references to the objects, it can create a bunch upfront based on and educated guess and expanded if needed at runtime, uses a vector behind the scenes and a pointer to the last unused item.
Then you just run though your linked list in the update function advancing and collision testing. It is then extremely fast to add/remove projectiles from the linked list and return/retrieve them from the pool. Most of the time there will be 0 allocations and 0 vector resizing/copying. It is not as cache friendly as blasting though a flat vector but plenty fast enough and the ease of implementation is a real plus.
There are no doubt other ways, this is just something I have used successfully many times and is both easy on the GPU and minimises memory allocation/GC.