Allocating Vectors (Or Vectors of Vectors) Dynamically

allocating vectors (or vectors of vectors) dynamically

Dynamically allocating arrays is required when your dimensions are given at runtime, as you've discovered.

However, std::vector is already a wrapper around this process, so dynamically allocating vectors is like a double positive. It's redundant.

Just write (C++98):

#include <vector>

typedef std::vector< std::vector<double> > matrix;
matrix name(sizeX, std::vector<double>(sizeY));

or (C++11 and later):

#include <vector>

using matrix = std::vector<std::vector<double>>;
matrix name(sizeX, std::vector<double>(sizeY));

Can you dynamically allocate a class with a vector as a field in C++?

A vector<foo> consists of two parts: a fixed-size block consisting of a pointer and a count of elements, and a variable-sized block which the pointer points to. When you create a new vector<foo>, it contains no foos; the count of elements is zero, and the pointer (depending on implementation) is likely null. When you destroy the vector (which happens when you delete vu), it frees the variable-sized block.

C++ Dynamic allocation of vectors in vector?

list.push_back(vector<int>());

vector<int>() creates a temporary vector<int> object and initializes it (i.e., it calls the default constructor for that object). push_back then copies that temporary object into the list.

In C# (and "other garbage collected languages"), new is used to create new objects, whose lifetimes are controlled by the garbage collector.

In C++, new is only used to dynamically allocate an object (and you are responsible for managing its lifetime, by using a smart pointer). The syntax T() (where T is the name of a type) is used to create a temporary object.

Vector of new vectors

You would need to free them with delete not delete [] because a vector is not an array.

But I wouldn't see any reason why you wouldn't use

std::vector<std::vector<double>>

This way you wouldn't need to worry about the allocation of the vector

Creating a dynamically-allocated array of std::vectors

If you want to create an 100 vectors each containing 100 integers, just use multiple (nested) vectors:

std::vector<std::vector<int> > x(100, std::vector<int>(100));

What's the safe way to dynamically allocate vector in C++

The call of delete[] is not the same as the call of delete (note the square brackets).

You pair calls of delete with calls of new, and calls of delete[] with calls of new SomeType[someCount].

In your case, you allocated a single object, not an array. Your object happens to represent a vector, which is an array, but it does not matter to C++: you allocated it with a "single" new, so you cannot apply an "array" delete[] to it.

Hence, you need to delete it using the regular delete operator:

delete mtx;

Note: there is rarely a situation when you should allocate std::vector<T> dynamically. The object that represents std::vector<T> itself is very small; the data is stored elsewhere, and is allocated dynamically. So you might as well use

VecStrInt mtx;

and skip delete altogether.

What is the difference between static and dynamic allocation of vector in c++?

The following two statements create a vector<> however there are several differences between the two.

vector<int> v1;
vector<int> *v2 = new vector<int>();

First of all the actual vector data storage is going to be allocated from the heap or whatever source the designated memory allocator uses (see Where does a std::vector allocate its memory?) and this is the same for both.

The two differences are (1) where the vector<> management data is stored and {2} the lifetime for the vector<> and its allocated memory.

In the first case the vector<> management data is stored on local memory, the stack, and when the vector<> variable goes out of scope, the destructor is called to eliminate the vector data storage space on the heap and the vector management space on the stack. In the first case when the vector<> variable goes out of scope, the vector<> memory is properly released.

In the second case both the vector<> storage data space and the vector<> management space is on the heap.

So when the pointer variable containing the address of the vector<> goes out of scope, the destructor for the vector<> itself is not called. The result is memory that is not recovered since the destructor that would clean up and release the allocated memory for both the data storage area of the vector<> and the management storage area is never called.

One possibility for the second case to ensure that the vector<> is cleaned up properly is to use a smart pointer which when it goes out of scope will also trigger the destructor for the thing pointed to.

In most cases the need for the second case, using new to create the vector<> is rare and the first case is not only the most common but also safer.

C++ vector of class objects and dynamic memory allocation - part 2

This is because of a simple reason. When you erase an entry, the array needs to remove that "bubble" (which is the empty slot) and compact the array. Which means that it needs to move some stuff. So when moving, what they do is something like this,

// Form the MSVC xutility.h file.
for (; _First != _Last; ++_Dest, (void) ++_First) {
*_Dest = _STD move(*_First);
}

As you can see, the way they move it is by moving the individual entries. This means that you call the copy assign/ move assign operator of the object Buffer. But you haven't defined any assignment operators, but a move constructor. This tells the compiler that,

"Hey, this Buffer object only has a move constructor. Maybe the user just wants to construct the class by moving another. So it cant have any other assignments (both copy and move)"

So now the compiler doesn't generate them for you. This means that you now cant copy or move another Buffer to another (unless you move construct it). That's the reason for the error.

The solution is to add a move assign operator.

Buffer& operator=(Buffer&& other)
{
S = std::move(other.S);
NAME = std::move(other.NAME);
DATA = other.DATA;

other.DATA = nullptr; // Make sure to set it to nullptr.

return *this;
}


Related Topics



Leave a reply



Submit