C++ implementation of an array of vectors - c++

Background: I want to implement a 3-d collision detection algorithm and would like to fragment the search space into cubes so that I only check for collisions when objects are close enough.
Actual Question: I was thinking of using an array of vectors to store pointers to the objects I am going to iterate over. For example box[0][0][0] would be a vector holding pointers to the objects in one corner of the simulation space. Regardless of whether this is an optimal solution, I am wondering how c++ handles arrays of vectors. Would the array hold pointers to the vectors so that their subsequent re-allocation have no effect on the validity of the array, or would the vectors be created inside the array and then moved out, causing undefined behavior?
Similar questions did not have answers specific to this implementation detail. Sorry if this is actually answered elsewhere and I missed it.

An STL vector holds a pointer to a heap buffer that contains the actual data. This allows the vector to resize the buffer on demand without invalidating the vector object itself. (See documentation of vector)
So, to answer your question. An array of vectors will not become invalid if one of the vectors needs to be resized. An array of pointers to vectors would also not become invalid if one of the vectors needs to be resized.

In STL a vector is an implementation of a dynamic array ( an array that can be resided on the fly). This essentially means that the array is dynamically allocated, and the user gets a pointer to the array on the heap. When more space is needed, a new array is allocated (usually double of it's previous size), the contents of the old one is copied over and the old array freed. And that is how data consistency is handled.
Now, when you have a array of vectors, statically allocated like the question shows, you have in memory (stack, or .data section, depending where you declare this array) an or 3 vector objects, allocated one after the other in memory, each one will hold a pointer to the an array allocated on the heap.
I hope this answers your question.

Related

how c++ vector<vector<int>> manages memory

vector container holds object in continuous memory. it is easy to understand for cases like vector. but what if it is a vector of vectors, like vector>, each vector in this vector of vectors can have different length. how does it manage the memory? Does it allocate a fixed length vector every time we push in a new vector? if so, what will happen if the first vector grows out of size during push_back. would it trigger a full vector of vector reallocate and copy/move?
A vector is a pointer to a dynamic array. If you push_back and find you're out of space in the array you have, you allocate a new, bigger array, copy over everything from the old array, and then stick the new value in.
If you have a vector of vectors, the same holds true for each of the inner vectors.
What you need to understand here is that a vector of vectors (unlike a 2D array), is not contiguous in memory. Each of the inner vectors' arrays can be stored anywhere in memory. Or in other words, "each vector in a vector of vectors is a completely different vector. Each with their own, completely separate and separately managed buffer.1"
1. Thanks to user4581301 for this!
A vector contains a pointer to a contiguous memory block. When it runs out of memory, it allocates a new memory block. A vector of vectors is just a vector of pointers to memory blocks. Although each memory block is a contiguous block, they are not necessarily contiguous to each other, that is, not necessarily when one vector ends, the next one starts, there is almost always a gap.
Why the not necessarily and almost always semantics? Because it depends on the memory allocator you're using and on the operating system internals. Ultimately, it's (one of) the job(s) of the OS to allocate and serve memory blocks to user-space programs.

Does std::vector have to resize if the elements it contains grow in size?

I apologize if this is too basic a question to ask here; I've been reading a bit about std::vector and I understand that it has to resize when the size reaches capacity. This can be an expensive operation if the objects it contains are large since it has to copy every one of them.
My question is: how does std::vector handle the actual size of the objects it contains growing? Suppose I initialize some
std::vector<Obj> vec(100);
And each Obj is initialized to something very small. But what if I then do something like
vec[14].ENGORGIO()
So that it now takes much more memory. Since the elements of std::vector are stored in contiguous memory, does this mean that it has to resize (expensively!)
To avoid this kind of thing, should I instead be storing pointers in a vector rather than the objects themselves? Like so
std::vector< std::unique_ptr<Obj> > vec;
Thank you
The size of a data type in C++ is set at compile time and cannot change. The data type may contain references to other objects, and these other objects can vary in size, but the size of the reference, and thus the data type, is unchanging.
Consider a vector of vectors. The inner vector may contain 0 elements or billions and billions and it will always be the same size. The outer vector only knows that it contains 0 or more vectors and knows nothing about what is contained inside the inner vectors.
You do not have to worry about this.
Each type has a size, and all objects of that type have the same size. The size of an object never changes throughout the program. Therefore the scenario that you describe does not exist.
The way vector "resizes" without changing the size of the vector object is achieved through indirection. The elements are not part of the memory of the object. Instead, the vector points to a buffer in dynamic memory. Resizing is done by creating a bigger dynamic buffer, and copying the elements from the old one before destroying the old buffer.

Memory layout of 2D area

How is a 2D area layout in memory? Especially if its a staggered area. Given, to my understanding, that memory is contiguous going from Max down to 0, does the computer allocate each area in the area one after the other? If so, should one of the areas in the area need to be resized, does it shift all the other areas down as to make space for the newly sized area?
If specifics are needed:
C++17/14/11
Clang
linux x86
Revision: (thanks user4581301)
I'm referring to having a vector<vector<T>> where T is some defined type. I'm not talking template programming here unless that doesn't change anything.
The precise details of how std::vector is implemented will vary from compiler to compiler, but more than likely, a std::vector contains a size_t member that stores the length and a pointer to the storage. It allocates this storage using whatever allocator you specify in the template, but the default is to use new, which allocates them off the heap. You probably know this, but typically the heap is the area of RAM below the stack in memory, which grows from the bottom up as the stack grows from the top down, and which the runtime manages by tracking which blocks of it are free.
The storage managed by a std::vectoris a contiguous array of objects, so a vector of twenty vectors of T would contain at least a size_t storing the value 20, and a pointer to an array of twenty structures each containing a length and a pointer. Each of those pointers would point to an array of T, stored contiguously in memory.
If you instead create a rectangular two-dimensional array, such as T table[ROWS][COLUMNS], or a std::array< std::array<T, COLUMNS>, ROWS >, you will instead get a single continuous block of T elements stored in row-major order, that is: all the elements of row 0, followed by all the elements of row 1, and so on.
If you know the dimensions of the matrix in advance, the rectangular array will be more efficient because you’ll only need to allocate one block of memory. This is faster because you’ll only need to call the allocator and the destructor one time, instead of once per row, and also because it will be in one place, not split up over many different locations, and therefore the single block is more likely to be in the processor’s cache.
vectors are thin wrappers around a dynamically allocated array of their elements. For a vector<vector<T>>, this means that the outer vector's internal array contains the inner vector structures, but the inner vectors allocate and manage their own internal arrays separately (the structure contains a pointer to the managed array).
Essentially, the 2D aspect is purely in the program logic; the elements of any given "row" are contiguous, but there is no specified spacial relationship between the rows.
True 2D arrays (where the underlying memory is allocated as a single block) only really happen with C-style arrays declared with 2D syntax (int foo[10][20];) and nested std::array types, or POD types following the same basic design.

How to reuse a memory block previously allocated to a vector in c++

I have multiple vectors of structure objects for different structures. Now I want to reuse the same memory for all the vector objects.i.e,Once my work is done with one vector i want to erase its elements from the memory and assign that memory to the other vector.
i.e.The first vector is of one structure type object and the second vector is a structure type object of a completely different structure.
I am using windows 8.1 64-bit.
When you erase vector elements, the memory allocated for the vector elements is not freed until you call std::vector::shrink_to_fit. Thus you do not have to do special actions to reuse the allocated memory.
It is not clean what you mean under
Once my work is done with one vector i want to erase its elements from
the memory and assign that memory to the other vector.
You could continue using the same vector with the same memory, or you can call v1.swap(v2) to exchange allocated memories of two vectors, or you can move allocated memory of one vector to another v2 = std::move(v1).
It is applicable to vectors containing elements of a same type or pointers, that is not suitable to your case.
Being able to move allocated memory from a vector of one type to a vector containing another is not a feature supported by std::vector. I would suggest writing/finding another container that fits your needs.

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.