[ACCEPTED]-C++ std::vector vs array in the real world-c++-standard-library

Accepted answer
Score: 27

A: Almost always [use a vector instead of 74 an array]. Vectors are efficient and flexible. They 73 do require a little more memory than arrays, but 72 this tradeoff is almost always worth the 71 benefits.

That's an over-simplification. It's 70 fairly common to use arrays, and can be 69 attractive when:

  • the elements are specified 68 at compile time, e.g. const char project[] = "Super Server";, const Colours colours[] = { Green, Yellow };

    • with C++11 it will be equally concise to initialise std::vectors with values

  • the number of elements 67 is inherently fixed, e.g. const char* const bool_to_str[] = { "false", "true" };, Piece chess_board[8][8];

  • first-use performance 66 is critical: with arrays of constants the 65 compiler can often write a memory snapshot 64 of the fully pre-initialised objects into 63 the executable image, which is then page-faulted 62 directly into place ready for use, so it's 61 typically much faster that run-time heap 60 allocation (new[]) followed by serialised construction 59 of objects

    • compiler-generated tables of const data 58 can always be safely read by multiple threads, whereas 57 data constructed at run-time must complete 56 construction before other code triggered 55 by constructors for non-function-local static variables 54 attempts to use that data: you end up needing 53 some manner of Singleton (possibly threadsafe 52 which will be even slower)

    • In C++03, vectors created 51 with an initial size would construct one 50 prototypical element object then copy construct 49 each data member. That meant that even 48 for types where construction was deliberately 47 left as a no-operation, there was still 46 a cost to copy the data elements - replicating 45 their whatever-garbage-was-left-in-memory 44 values. Clearly an array of uninitialised 43 elements is faster.

  • One of the powerful features 42 of C++ is that often you can write a class (or 41 struct) that exactly models the memory layout 40 required by a specific protocol, then aim 39 a class-pointer at the memory you need to 38 work with to conveniently interpret or assign 37 values. For better or worse, many such 36 protocols often embed small fixed sized 35 arrays.

  • There's a decades-old hack for putting 34 an array of 1 element (or even 0 if your 33 compiler allows it as an extension) at the 32 end of a struct/class, aiming a pointer 31 to the struct type at some larger data area, and 30 accessing array elements off the end of 29 the struct based on prior knowledge of the 28 memory availability and content (if reading 27 before writing) - see What's the need of array with zero elements?

  • classes/structures 26 containing arrays can still be POD types

  • arrays 25 facilitate access in shared memory from 24 multiple processes (by default vector's internal 23 pointers to the actual dynamically allocated 22 data won't be in shared memory or meaningful 21 across processes, and it was famously difficult 20 to force C++03 vectors to use shared memory like 19 this even when specifying a custom allocator 18 template parameter).

  • embedding arrays can 17 localise memory access requirement, improving 16 cache hits and therefore performance

That 15 said, if it's not an active pain to use 14 a vector (in code concision, readability or performance) then 13 you're better off doing so: they've size(), checked 12 random access via at(), iterators, resizing 11 (which often becomes necessary as an application 10 "matures") etc.. It's also often 9 easier to change from vector to some other Standard 8 container should there be a need, and safer/easier 7 to apply Standard algorithms (x.end() is better 6 than x + sizeof x / sizeof x[0] any day).

UPDATE: C++11 introduced 5 a std::array<>, which avoids some of the costs of vectors 4 - internally using a fixed-sized array to 3 avoid an extra heap allocation/deallocation 2 - while offering some of the benefits and 1 API features: http://en.cppreference.com/w/cpp/container/array.

Score: 21

One of the best reasons to use a vector as opposed 20 to an array is the RAII idiom. Basically, in 19 order for c++ code to be exception-safe, any 18 dynamically allocated memory or other resources 17 should be encapsulated within objects. These 16 objects should have destructors that free 15 these resources.

When an exception goes unhandled, the 14 ONLY things that are gaurenteed to be called 13 are the destructors of objects on the stack. If 12 you dynamically allocate memory outside 11 of an object, and an uncaught exception 10 is thrown somewhere before it is deleted, you 9 have a memory leak.

It's also a nice way 8 to avoid having to remember to use delete.

You 7 should also check out std::algorithm, which provides a 6 lot of common algorithms for vector and other 5 STL containers.

I have on a few occasions 4 written code with vector that, in retrospect, probably 3 would have been better with a native array. But 2 in all of these cases, either a Boost::multi_array or a Blitz::Array would 1 have been better than either of them.

Score: 7

A std::vector is just a resizable array. It's 7 not much more than that. It's not something 6 you would learn in a Data Structures class, because 5 it isn't an intelligent data structure.

In 4 the real world, I see a lot of arrays. But 3 I also see a lot of legacy codebases that 2 use "C with Classes"-style C++ programming. That 1 doesn't mean that you should program that way.

Score: 5

I am going to pop my opinion in here for 53 coding large sized array/vectors used in 52 science and engineering.

The pointer based 51 arrays in this case can be quite a bit faster 50 especially for standard types. But the pointers 49 add the danger of possible memory leaks. These 48 memory leaks can lead to longer debug cycle. Additionally 47 if you want to make the pointer based array 46 dynamic you have to code this by hand.

On 45 the other hand vectors are slower for standard 44 types. They also are both dynamic and memory 43 safe as long as you are not storing dynamically 42 allocated pointers in the stl vector.

In 41 science and engineering the choice depends 40 on the project. how important is speed vs 39 debug time? For example LAAMPS which is 38 a simulation software uses raw pointers 37 that are handled through their memory management 36 class. Speed is priority for this software. A 35 software I am building, i have to balance 34 speed, with memory footprint and debug time. I 33 really dont want to spend a lot of time 32 debugging so i am using the STL vector.

I 31 wanted to add some more information to this 30 answer that I discovered from extensive 29 testing of large scale arrays and lots of 28 reading the web. So, another problem with 27 stl vector and large sized arrays (one million 26 +) occurs in how memory gets allocated for 25 these arrays. Stl vector uses the std::allocator 24 class for handling memory. This class is 23 a pool based memory allocator. Under small 22 scale loading the pool based allocation 21 is extremely efficient in terms of speed 20 and memory use. As the size of the vector 19 gets into the millions, the pool based strategy 18 becomes a memory hog. This happens because 17 the pools tendency is to always hold more 16 space than is being currently used by the 15 stl vector.

For large scale vectors you 14 are either better off writing your own vector 13 class or using pointers (raw or some sort 12 of memory management system from boost or 11 the c++ library). There are advantages and 10 disadvantages to both approaches. The choice 9 really depends on the exact problem you 8 are tackling (too many variables to add 7 in here). If you do happen to write your 6 own vector class make sure to allow the 5 vector an easy way to clear its memory. Currently 4 for the Stl vector you need to use swap 3 operations to do something that really should 2 have been built into the class in the first 1 place.

Score: 4

Rule of thumb: if you don't know the number 16 of elements in advance, or if the number 15 of elements is expected to be large (say, more 14 than 10), use vector. Otherwise, you could 13 also use an array. For example, I write 12 a lot of geometry-processing code and I 11 define a line as an ARRAY of 2 coordinates. A 10 line is defined by two points, and it will 9 ALWAYS be defined by exactly two points. Using 8 a vector instead of an array would be overkill 7 in many ways, also performance-wise.

Another 6 thing: when I say "array" I really DO MEAN 5 array: a variable declared using an array 4 syntax, such as int evenOddCount[2]; If you consider choosing 3 between a vector and a dynamically-allocated 2 block of memory, such as int *evenOddCount = new int[2];, the answer is 1 clear: USE VECTOR!

Score: 3

It's a rare case in the real world where 15 you deal with fixed collections, of a known 14 size. In almost all cases there is a degree 13 of the unknown in exactly what size of data 12 set you will be accommodating in your program. Indeed 11 it is the hallmark of a good program that it 10 can accomodate a wide range of possible 9 scenarios.

Take these (trivial) scenarios 8 as examples:

  • You have implemented a view controller to track AI combatants in a FPS. The game logic spawns a random number of combatants in various zones every couple of seconds. The player is downing AI combatants at a rate known only at run time.
  • A lawyer has accessed the Municipal Court website in his state and is querying the number of new DUI cases that came in over the night. He chooses to filter the list by a set of variables including time the accident occurred, zip code, and arresting officer.
  • The operating system needs to maintain a list of memory addresses in use by the various programs running on it. The number of programs and their memory usage changes in unpredictable ways.

In any of these cases a good 7 argument can be made that a variable size 6 list (that accommodates dynamic inserts 5 and deletes) will perform better than a 4 simple array. With the main benefits coming 3 from reduced need to alloc/dealloc memory 2 space for the fixed array as you add or 1 remove elements from it.

Score: 0

As far as arrays are considered, simple 10 integer or string arrays are very easy to 9 use. On the other hand, for common functions 8 like searching,sorting,insertion,removal, you 7 can achieve much faster speed using standard 6 algorithms (built in library functions) on 5 vectors. Specially if you are using vectors 4 of objects. Secondly there is this huge 3 difference that vectors can grow in size 2 dynamically as more objects are inserted. Hope 1 that helps.

More Related questions