A C++ container similar to dynamic array? - c++

In this set of slides the author highly recommends to avoid pointers in C++ programs. Specially in slide 6, using vectors are suggested instead of dynamic arrays. While I believe vectors are much safer to use, for example they avoid memory leaks when an exception happens, they have extra memory overhead. This post says that vectors can consume up to twice the size of existing elements in the vector. Unfortunately, this feature causes my program to abort in my system with limited amount of available memory.
Is there a C++ container similar to dynamic arrays, getting the fixed (or rarely changing) number of elements in runtime, and provide the same safety as containers? The closest thing I could find (here) was array which required compile-time specified size provided in template.

You can use the array specialization of std::unique_ptr:
std::unique_ptr<int[]> arr(new int[5]);
This will safely manage the memory for you.

If you know the fixed size, just calling reserve(n) on the vector should do the trick. While it isn't guaranteed not to use more space, I don't know of any implementations that don't just allocate space for exactly that number of elements (assuming it is greater than the current capacity(), of course).

Related

Should I use std::vector instead of array [duplicate]

This question already has answers here:
When to use vectors and when to use arrays in C++?
(2 answers)
Closed 5 years ago.
The way I see this, they both have the same function except std::vector seems more flexible, so when would I need to use array, and could I use std::vector only?
This is not a new question, the original questions didn't have the answers I was looking for
One interesting thing to note is that while iterators will be invalidated in many functions with vectors, that is not the case with arrays. Note: std::swap with std::array the iterator will still point to the same spot.
See more:
http://en.cppreference.com/w/cpp/container/array
Good summary of advantages of arrays:
https://stackoverflow.com/a/4004027/7537900
This point seemed most interesting:
fixed-size arrays can be embedded directly into a struct or object,
which can improve memory locality and reducing the number of heap
allocations needed
Not having tested that, I'm not sure it's actually true though.
Here is a discussion in regards to 2D Vectors vs Arrays in regards to the competitive programming in Code Chef:
https://discuss.codechef.com/questions/49278/whether-to-use-arrays-or-vectors-in-c
Apparently memory is not contiguous in 2 dimensions in 2D vectors, only one dimension, however in 2D arrays it is.
As a rule of thumb, you should use:
a std::array if the size in fixed at compile time
a std::vector is the size is not fixed at compile time
a pointer on the address of their first element is you need low level access
a raw array if you are implementing a (non standard) container
Standard containers have the ability to know their size even when you pass them to other function, what raw arrays don't, and have enough goodies to never use raw arrays in C++ code without specific reasons. One could be a bottleneck that would require low level optimization, but only after profiling to identify the bottleneck. And you should benchmark in real condition whether the standard containers actually add any overload.
The only good reason I can think of is if you implement a special container. As standard containers are not meant to be derived, you have only two choices, either have you class contain a standard container and end in a container containing a container with delegations everywhere, or mimic a standard container (by copying code from a well knows implementation), and specialize it. In that case, you will find yourself managing directly raw arrays.
When using std:vector, the only performance hit would be when the capacity is reached, as the memory must be relocated to accomodate a larger number of objects in contiguous memory space on the heap
Thus here is a summary of both in regards to flexibility and performance:
std::array; Reallocation is not possible and thus no perfomance hit will occur due to relocation of memory on the heap.
std::vector; Only affects performance if capacity is exceeded and reallocation occurs. You can use reserve(size) to provide a rough estimate to the maximum amount of objects you'll need. This allows greater flexibility compared to std::array but will of course, have to reallocate memory if the reserved space is exceeded.

What is the difference between std::vector and llvm::SmallVector? which one to use when?

I am trying to understand the use of SmallVector container in LLVM. I think std::vector can be used in place of small vector. Also what happens if we push more elements in llvm::SmallVector than its size?
llvm::SmallVector is a vector optimized for small arrays. This optimization comes from not performing heap allocations for a limited number of elements.
In the event that you add more elements than are described to be allocated using automatic storage it will fall back to the behavior of std::vector and allocate larger and larger arrays.
llvm::SmallVector<int, 10> smallVector;
for(int i = 0; i < 10; i++)
{
smallVector.push_back(i);
}
// No heap allocations have been performed up to this point.
smallVector.push_back(11);
// Only 10 spaces for non heap allocated elements,
// so the push_back above causes a heap allocation.
SmallVector can have a performance benefit when you know you will consistently have a small number of elements and won't run into heap allocations. This performance benefit comes at the cost of exception safety and a dependency on the llvm libraries.
What is the difference between std::vector and LLVM::SmallVector?
I assume that you are familiar with the standard vector. llvm::SmallVector is described in the documentation:
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
It contains some number of elements in-place, which allows it to avoid heap allocation when the actual number of elements is below that threshold. This allows normal "small" cases to be fast without losing generality for large inputs.
Note that this does not attempt to be exception safe.
which one to use when?
Use std::vector when:
You need exception safety OR
You don't want extra dependencies beyond the standard library OR
The container isn't a bottleneck OR
Performance doesn't even matter OR
The vector is going to be large anyway, so the optimization wouldn't have an impact
Use a small-optimized implementation (such as llvm::SmallVector, or another implementation) when
None of the above applies
Also what happens if we push more elements in llvm::SmallVector than its size?
When the internal small buffer is exhausted, a dynamic buffer is allocated and it will behave like std::vector.

Dynamic arrays vs STL vectors exact difference?

What is the exact difference between dynamic arrays and vectors. It was an interview question to me.
I said both have sequential memory.
Vectors can be grown in size at any point in the code. He then said even dynamic arrays can be grown in size after creating.
I said vectors are error free since it is in the standard library. He said he will provide as .so file of dynamic arrays which is error free and has all the qualities on par with STL.
I am confused and didn't answer the exact difference. When I searched on Internet, I had seen the above statements only.
Can someone please explain me the exact difference? And what was the interviewer expecting from me?
He said he will provide as .so file of dynamic arrays which is error free and has all the qualities on par with STL.
If his dynamic array class does the same as std::vector (that is: it implements RAII to clean up after itself, can grow and shrink and whatever else std::vector does), then there's only one major advantage std::vector has over his dynamic array class:
std::vector is standardized and everybody knows it. If I see a std::vector in some piece of code, I know exactly what it does and how it is supposed to be used. If, however, I see a my::dynamic_array, I do not know that at all. I would need to have to look at its documentation or even — gasp! — implementation to find out whether my_dynamic_array::resize() does the same as std::vector::resize().
A great deal here depends on what he means by a "dynamic array". Most people mean something where the memory is allocated with array-new and freed with array-delete. If that's the intent here, then having qualities on a par with std::vector simply isn't possible.
The reason is fairly simple: std::vector routinely allocates a chunk of memory larger than necessary to hold the number of elements currently being stored. It then constructs objects in that memory as needed to expand. With array-new, however, you have no choice -- you're allocating an array of objects, so if you allocate space for (say) 100 objects, you end up with 100 objects being created in that space (immediately). It simply has no provision for having a buffer some part of which contains real objects, and another part of which is just plain memory, containing nothing.
I suppose if yo want to stretch a point, it's possible to imitate std::vector and still allocate the space with array-new. To do it, you just have to allocate an array of char, and then use placement new to create objects in that raw memory space. This allows pretty much the same things as std::vector, because it is nearly the same thing as std::vector. We're still missing a (potential) level of indirection though -- std::vector actually allocates memory via an Allocator object so you can change exactly how it allocates its raw memory (by default it uses std::allocator<T>, which uses operator new, but if you wanted to, you could actually write an allocator that would use new char[size], though I can't quite imagine why you would).
You could, of course, write your dynamic array to use an allocator object as well. At that point, for all practical purposes you've just reinvented std::vector under a (presumably) new name. In that case, #sbi is still right: the mere fact that it's not standardized means it's still missing one of the chief qualities of std:::vector -- the quality of being standardized and already known by everybody who knows C++. Even without that, though, we have to stretch the phrase "dynamic array" to (and I'd posit, beyond) the breaking point to get the same qualities as std::vector, even if we ignore standardization.
I expect they wanted you to talk about the traps of forgetting to delete the dynamic array with operator delete[] and then got confused themselves when they tried to help you along; it doesn't make much sense to implement a dynamic array as a plain class since it bakes in the element type.
The array memory allocated for vectors is released when the vector goes out of scope, in case the vector is declared on the stack (the backing array will be on the heap).
void foo() {
vector<int> v;
// ... method body
// backing array will be freed here
}
It says here: "Internally, vectors use a dynamically allocated array to store their elements."
Underlying concept of vectors is dynamically allocated array.
http://www.cplusplus.com/reference/vector/vector/
Maybe it's that dynamic array you would go through the copy process to a new dynamic array whenever you want to resize, but you are able to control when it does that depending on your knowledge of the data going into the array.
Whereas a vector uses the same process, but a vector does not know if it will grow or not later, so it probably allocates extra storage for possible growth in size, therefore it COULD possibly consume more memory space than intended to manage itself compared to dynamic arrays.
So, I'd say the difference is to use a vector when managing it's size is not a big deal, where you would use a dynamic array when you would rather do the resizing yourself.
Arrays have to be deallocated explicitly if defined dynamically whereas vectors are automatically de-allocated from heap memory.
Size of array cannot be determined if dynamically allocated whereas Size of the vector can be determined in O(1) time.
3.When arrays are passed to a function, a separate parameter for size is also passed whereas in case of passing a vector to a function, there is no such need as vector maintains variables which keeps track of size of container at all times.
4.When we allocate array dynamically then after size is initialized we cannot change the size whereasin vector we can do it.

vector with constant size

I am looking for a C++ data type similar to std::vector but without the overhead related to dynamic resizing. The size of the container will remain constant over its lifetime. I considered using boost::array, however, that is not appropriate because it requires the size of the array to be known at compile time, which is not the case in my situation.
Measure if the dynamic resizing has really any performance impact before using anything non-standard.
Tip: With vector.reserve there will never be any array-reallocation.
There's no overhead in reallocation if you don't reallocate std::vector. So either:
construct the std::vector with a known size ahead (std::vector x(100))
call reserve(n) after construction to make sure that at least n elements can be pushed into the vector before reallocation occurs.
The overhead induced by dynamic resizing capability of std::vector is virtually non-existent.
If you needed an array of compile-time size, looking for something more efficient than std::vector would indeed be a good idea in many cases.
But the difference between fixed run-time size and dynamic run-time size is negligible. std::vector is a perfect solution in this case.
I've used a template class based on ideas from STLSoft's auto_buffer (I cobbled together my own implementation from Matthew Wilson's Imperfect C++ book along with some ideas from the STLSoft implementation). It allocates the array by default on the stack (or embedded in the class object) if it's small enough (based on a template parameter you provide). If your runtime allocation is larger than that, the array storage comes from the heap.
http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html
So the nice thing about this class is that for smaller small sizes, the allocation is essentially a no-op.
If the size of the array is not known at compile time, then the only option in C++ is a dynamically-allocated array. You can use a std::vector to guarantee RAII. As others have said, the fact that std::vectors can be resized doesn't mean that you have to resize them. Create the std::vector with the correct size, and then don't call anything that would resize it.

Some questions about Vector in STL

I have some questions about vector in STL to clarify.....
Where are the objects in vector allocated? heap?
does vector have boundary check? If the index out of the boundary, what error will happen?
Why array is faster than vector?
Is there any case in which vector is not applicable but array is a must?
In a contiguous memory block on the heap. A vector<int> allocates memory the same way new int[x] would.
Only if you use the at method. It throws an std::out_of_range exception if the boundary check fails. The operator[] doesn't perform bounds checking.
Because an array gives direct access to memory, while accessing a vector element most likely involves a method call. The difference can be ridiculously small though, especially if your compiler decides to inline the calls.
In general, you'll use a vector if you want your container to have a dynamic size, and a simple array if a known fixed size is enough. Be sure to check out the other containers, like deque and list, to be sure you pick the most appropriate one. Otherwise, if you need to deal with non-C++ APIs, you'll obviously need to have access to a regular array. (edit) #BillyONeal says you should use &vector[0] to get the address of the underlying array, but use it with care since it can change if the vector's capacity changes.
Where are the objects in vector
allocated? heap?
It depends on the STL implementation, but in all likelihood on the heap, yes.
does vector have boundary check? If the index out of the boundary,
what error will happen?
Yes, a vector grows dynamically, you can check its size using the capacity() member function. If it should run out of space, it generally allocates more space using the reserve() member function.
Why array is faster than vector?
Arrays can be faster because they are plain data that does not need to be accessed through a wrapper object such as vector. You can think of a vector as neatly packaged array for your convenience.
Is there any case in which vector is
not applicable but array is a must?
I think there can be times where an array is preferable over a vector. For example, when dealing with legacy C code or when speed is of utmost importance. But generally you can solve any array problem by containing the data in an STL vector.
Ad 4.: When dealing with legacy interfaces (e.g. POSIX) arrays may be a must.
On the heap (assuming you use the standard allocator, which is the default)
It is not boundary checked when using operator[], but it is if you use the member function at (e.g. my_vec.at(0)). If you use at and the index is out or bounds, it throws an std::out_of_range exception.
Arrays aren't generally faster. It depends whether or not the vector's operator[] calls are inlined or not. Most modern compilers should index it though, as it is just a single array index.
In general, normal arrays can be replaced by vectors. You shouldn't really use a std::vector on the public interface of a library, and manu library APIs require raw C-style arrays.
By default contents are allocated dynamically. (But I suppose you can provide an allocator that gets the memory from some place else.)
The at method does bounds checks and throws an out_of_range. Other methods may or may not check bounds, depending on implementation and settings.
I would assume a vector to be slower than an array when it does something different from an array. For example, dynamic allocation is costly, so vector has a cost that arrays don't have. Dynamically resizing a vector is costly, whereas an array can't be resized at all. I wouldn't expect to see any difference when accessing the elements (except for possible run-time checks done by the implementation which you should be able to turn off if desired).
I don't know of such a scenario. You can always get a pointer to the underlying array of a vector with &vec[0]. However, a vector can be an overkill if you don't need any of the features it provides - mostly the ability to (re)size it dynamically. In such cases an array could do just fine, but note that there are classes that make an array a first-class object too (std::tr1::array or boost::array) which make the array copyable and not decay into a pointer.