How to allocate memory to Vector dynamically ?
vector<Point> vInPts; // My Input Vector - i have dumped some value ( of size 6 )
// Doing Some calculation on the input vector points
vector<Point> vOutPts; // How to dynamically allocate memory for this output vector Points
Chances are you do not need to allocate the vector itself dynamically. Internally, the vector will allocate the memory it needs to store its elements dynamically, and will take care of managing this memory. So just declare the vector in automatic storage:
vector<Point> vOutPts;
You can allocate a predetermined amount of memory for the vector by calling std::vector::reserve.
If you absolutely must allocate the vector dynamically, make sure you know all about memory management, and read up on smart pointers and RAII.
If you know the size you want, then you can allocate and initialise enough elements with:
vOutPts.resize(size);
or you can create it with that size:
vector<Point> vOutPts(size);
Otherwise, you can grow the vector one element at a time:
vOutPts.push_back(some_point);
If you know (roughly) how many elements you want to push, then you could make that a bit more efficient by allocating some memory beforehand, without initialising any elements:
vOutPts.reserve(approx_size);
This way
vector <Point> *myvect= new vector<Point>()
But don't forget to call:
delete myvect
when you're done using it or else you'll create a leak.
Please notice that allocating the vector itself this way won't be the same as allocating dinamically the vector contents. This dynamic allocation of the vector itself should be done only if for example you intend to create a vector inside a function and return it by reference. Automatic memory management is easier to handle, less error prone and above all safer than dynamically allocating objects... and therefore whenever you don't have to you should avoid this dynamic allocation
Related
I want to grow a ::std::vector at runtime, like that:
::std::vector<int> i;
i.push_back(100);
i.push_back(10);
At some point, the vector is finished, and i do not need the extra functionality ::std::vector provides any more, so I want to convert it to a C-Array:
int* v = i.data();
Because I will do that more than once, I want to deallocate all the heap memory ::std::vector reserved, but I want to keep the data, like that (pseudo-code):
free(/*everything from ::std::vector but the list*/);
Can anybody give me a few pointers on that?
Thanks in advance,
Jack
In all the implementations I have seen, the allocated part of a vector is... the array itself. If you know that it will no longer grow, you can try to shrink it, to release possibly unused memory:
i.shrink_to_fit();
int* v = i.data();
Of course, nothing guarantees that the implementation will do anything, but the only foolproof alternative would be to allocated a new array, move data from the vector to the array and clear the vector.
int *v = new int[i.size];
memcpy(v, i.data, i.size * sizeof(int));
i.clear();
But I really doubt that you will have a major gain that way...
You can use the contents of a std::vector as a C array without the need to copy or release anything. Just make sure that std::vector outlives the need for your pointer to be valid (and that further modifications which could trigger a reallocation are done on the vector itself).
When you obtain a pointer to internal storage through data() you're not actually allocating anything, just referring to the already allocated memory.
The only additional precaution you could use to save memory is to use shrink_to_fit() to release any excess memory used as spare capacity (though it's not guaranteed).
You have two options:
Keep data in vector, but call shrink_to_fit. All overhead you'll have - is an extra pointer (to the vector end). It is available since C++ 11
Copy data to an external array and destroy the vector object:
Here is the example:
std::vector<int> vec;
// fill vector
std::unique_ptr<int[]> arr(new int[vec.size()]);
std::copy(vec.begin(), vec.end(), arr.get());
So I have a vector of vectors that is heap allocated:
std::vector<std::vector<int>>* matrix = new std::vector<std::vector<int>>();
After putting a considerable amount of data into matrix. What is the correct way to delete this object?
Does delete matrix deallocate all of the internal vectors?
Yes delete matrix; will be fine.
You may want to consider if you need to dynamically allocate your vector. Vectors always store their data on the free-store (heap) so they don't need to be dynamically allocated for that reason. They have a very small stack foot-print.
If you must allocate your vector dynamically then you should seriously consider using a smart pointer such as a std::unique_ptr or a std::shared_ptr, then you won't need to call delete at all:
auto matrix = std::make_unique<std::vector<std::vector<int>>>();
Yes, it does. delete matrix calls the destructor of the std::vector<std::vector<int>> before returning memory. The destructor call will call the destructor of all its elements, std::vector<int>.
Also, most usage of std::vector wouldn't require you to create it on the heap. I suspect the same with your case.
I have come against a problem with my pointer vectors...
And i got an idea what the problem might be:
When I create a pointer to a vector, the pointer reserves the size of the vector on the heap. So that basicly means, that the pointer now points to the memory of the vector without anything inside... When i now resize or pushback the vector, will the pointer now still point to the whole memory of the vector or just the memory which has been allocated at the beginning?
I also want to know, if there are some tricks you can do to fix that (if what i think is true). Is the "vector.reserve(n)" a method of accomplishing this? Or is there something i could do to overwrite the pointers memory adress, to a vector after it has been initialised?
"When I create a pointer to a vector, the pointer reserves the size of the vector on the heap.
No, it doesn't! When you create a pointer to a vector, you have a pointer. Nothing more. It doesn't point to anything yet, and it certainly hasn't reserved any "heap memory" for you.
You still need to actually create the vector that will be pointed-to.
std::vector<int>* ptr1; // just a pointer;
ptr1 = new std::vector<int>(); // there we go;
delete ptr1; // don't forget this;
auto ptr2 = std::make_shared<std::vector<int>>(); // alternatively...
Y'know, it's very rare that you need to dynamically-allocate a container. Usually you just want to construct it in the usual fashion:
std::vector<int> v;
That's it. No need for pointers.
When i now resize or pushback the vector, will the pointer now still point to the whole memory of the vector or just the memory which has been allocated at the beginning?
Regardless of how you constructed/allocated it, the vector itself never moves spontaneously (only the dynamic memory that it is managing for you internally), so you do not need to worry about this.
I also want to know, if there are some tricks you can do to fix that
No need, as there's nothing to fix.
Is the "vector.reserve(n)" a method of accomplishing this?
Theoretically, if this were a problem (which it isn't) then, yes, this could possibly form the basis of a solution.
Vector is class that has internal pointer to vector's elements using continuous block of memory in the heap. Long enough for all reserved vector's elements (capacity() method)
So, if you create vector (in local scope's stack OR in the heap - doesn't matter) it creates this layout
[ vector [ ptr-to-data ] ] --> HEAP: [ 1 ][ 2 ][ 3 ]
vector<int> v1(3); // whole vector instance in the stack
vector<int> *pv2 = new vector<int>(3); // pointer to vector in the heap
each of these 2 vector instances has its pointer to its elements in the heap as well
Vector manages its pointer to the data internally.
When you push_back() more elements than its current .capacty() it will re-allocate new continuous block of memory and copy-construct or move all old elements to this new block.
Is there a way to move a unique_ptr
unique_ptr<int[]> foo;
into a vector?
vector<int> bar;
No, you cannot just hand vector a piece of memory and expect it to use that as its array storage. A vector's storage must come from the allocator that the vector uses.
You could try to use allocator gimmicks to pawn the memory off to the vector in some way. But even that would be tricky, as the vector can allocate as many ints as it wants, regardless of what size you tell it.
You can move the contents of a unique_ptr into an element of the array. Say, if you had a vector<unique_ptr<int[]>>. But you can't just slap a piece of memory into a vector.
I wanted to initialize a vector of vectors that contain pointers to Courses. I declared this:
std::vector<std::vector<Course*> > *CSPlan =
new std::vector<std::vector<Course*> >(smsNum);
What I wanted to do by this is to have a vector of vectors, each inside vector is a vector that contains pointers to Courses, and I wanted the MAIN vector to be of size int smsNum. Furthermore, I wanted it on the heap.
My questions are:
Are both the main vector AND the inside vectors allocated on the heap? or is it only the MAIN vector is on the heap and its' indexes are pointers to other smaller vectors on the stack?
I declared it to be of size int smsNum so the Main vector is of size 10, but what about the smaller vectors? are they also of that size or are they still dynamic?
My goal in the end is to have a vector of vectors, both the Main vector and the child vectors on the heap, and ONLY the Main vector is of size smsNum, while the rest are dynamic.
Any structure that can grow as large as the user wants it to is going to be allocated on the heap. The memory stack, on the other hand, is used to allocate statically allocated variables, that the program has control of the size statically, during the compilation process.
Since you can have a loop like this:
for (i = 0; i < your_value; i++) {
vector.insert(...);
}
And considering your_value as an integer read from the standard input, the compiler have no control on how large will be your vector, i.e., it does not know what is the maximum amount of inserts you may perform.
To solve this, the structure must be allocated on the heap, where it may grow as large as the OS allows it to -- considering primary memory, and swap. As a complement, if you use the pointer to the vector, you'll be simply dynamically allocating a variable to reference the vector. This changes NOT the fact that the contents of the vector is, necessarily, being allocated on the heap.
You'll have, in your stack:
a variable "x" that stores the address of a variable "y";
And in your heap:
the value of the variable "y", that is a reference to your vector of vectors;
the contents of your vector of vectors (accessed by "y", that is accessed by "x").