How to Resize a 2D Vector of Objects Given the Width and Height

How can I resize a 2D vector of objects given the width and height?

You have to resize the outer and inner vectors separately.

myVector.resize(n);
for (int i = 0; i < n; ++i)
myVector[i].resize(m);

How can I resize a 2D C++ vector?

Given the vector is empty, you can simply resize the outer vector with preallocated inner vectors without the need of a loop:

matrix.resize(COL, vector<char>(ROW));

Alternatively, when initializing or if you want to reset a non-empty vector, you can use the constructor overload taking a size and initial value to initialize all the inner vectors:

matrix = vector<vector<char> >(COL, vector<char>(ROW));

Depending on whether your matrix is column- or row-major, you need to swap the arguments ROW and COL. The first one (the first parameter on the outer vector) is your first dimension to access the matrix, i.e. I assumed you access it with matrix[col][row].

How to re-size a multidimensional vector? C++

matrix.resize(x); // this will resize the outer vector to be of size x
for (int i = 0; i < x; i++)
{
matrix[x].resize(y); // this will attempt to access 1 passed the size you set.
}

I think you meant to type matrix[i].

But yes, std::vector::resize will resize both the outer and inner vectors as long as you make sure you loop properly.

Example

Resizing 2d vector - error

When you vector.resize(n) and n > vector.size() you are asking it to create n - vector.size() new elements. Vector needs to default construct them, since he doesn't know what arguments to use. If they are not default constructible, resize fails.

However, if you don't want Square to be default constructible you can change failing line to vector.reserve() - that only makes sure there is enough space for new elements, but doesn't actually create them. Then you can create them one by one in a loop using

squares[i].emplace_back(sf::Vector2f(i * size, j * size));

Oh, and by the way passing primitives by reference has suboptimal performance. Pass them by value unless you need them as out parameters.

2-D vector Size

Here

vector<vector<int>> d;
for (int i = 0; i < size; i++)
{
d[i].resize(size);
//...

d is a vector of size 0 and accessing d[i] is out of bounds. You seem to be aware that you first have to resize the inner vectors, but you missed to do the same for the outer one. I dont really understand how your code can run as far as printing anything for arr[0].size(); without segfaulting. Anyhow, the problem is that there is no element at arr[0].

Is there a quick way I can make a vector of vector using just one type of element?

Use the constructor

#include <vector>

int main() {
std::vector<std::vector<bool>> a(4, std::vector<bool>(5, false));
}

With C++17 you don't even need the types (wandbox):

#include <vector>

int main() {
std::vector a(4, std::vector(5, false));
}

Reshape 2D Vector in C++

Decided to follow my comment through. This answer heads pretty far into X-Y territory, but it should simplify things a great deal

#include <iostream>
#include <iomanip>
#include <vector>
#include <exception>

// wrapping class for 2D matrixes
class Matrix
{
private:
size_t rows, columns; // large, unsigned datatype. Don't want negative
// indices, so why allow them?
std::vector<int> matrix; // 1D vector. Simple and easy to handle.
// also often much faster than vector of vectors
// due to improved spatial locality helping
// predictability of data access
public:
// catchable exception should user request impossible dimension transformation
class BadDimsException: public std::exception
{
public:
const char* what() const noexcept
{
return "Invalid dimensions specified";
}
};

// build zero-filled Matrix
Matrix(size_t numrows, size_t numcols) :
rows(numrows), columns(numcols), matrix(rows * columns)
{
}

// build Matrix based on another Matrix with convertable dimensions
// All of the heavy lifting is performed in the member initializer list
// by simply copying data store of source Matrix
// if matrix cannot be transformed, the thrown exception leaves user with
// nothing to work with and no chance of trying to continue with an un-
// transformed matrix
Matrix(size_t numrows, size_t numcols, const Matrix & source) :
rows(numrows), columns(numcols), matrix(source.matrix)
{
if (rows * columns != source.rows * source.columns)
{ // Bad dimensions. Blow up.
throw BadDimsException();
}
}

// 2D to 1D mapping accessor
int & operator()(size_t row, size_t column)
{
// check bounds here
return matrix[row * columns + column];
}

// 2D to 1D mapping accessor for constant Matrix
int operator()(size_t row, size_t column) const
{
// check bounds here
return matrix[row * columns + column];
}

// dimension accessors
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
};

// stream formatter
std::ostream & operator<<(std::ostream & out, const Matrix & mat)
{
for (size_t row = 0; row < mat.getRows(); ++row)
{
for (size_t col = 0; col < mat.getColumns(); ++col)
{
std::cout << std::setw(5) << mat(row, col);
}
std::cout << '\n';
}
return out;
}

And to test/demonstrate usage:

int main()
{
Matrix one(2, 6); // make 2x6 matrix
int count = 0;

// set inputs to make errors really stand out
for (size_t row = 0; row < one.getRows(); ++row)
{
for (size_t col = 0; col < one.getColumns(); ++col)
{
one(row, col) = count++;
}
}

// print initial matrix
std::cout << one << '\n';

// make reshaped matrix
Matrix two(3,4, one);

//print reshaped Matrix
std::cout << two << '\n';
try
{
// make invalid reshaped matrix
Matrix three(3, 3, one);

// This should never print
std::cout << three << '\n';
}
catch (const Matrix::BadDimsException & bde)
{
// Yay! Caught error!
std::cout << bde.what() << '\n';
}
}

Getting subscript out of range after vector resize

Your resize call only affects new rows. All existing rows are unaffected.

But you're not even adding rows! You called resize and passed the same value as the current size. So nothing will happen. It seems you have a misunderstanding of how much magic and mind-reading happens inside this call.

You will need to iterate through your rows and resize each one. Here is one way you could do it:

typedef std::vector<std::vector<std::string>> StringMatrix;

void AddColumns(StringMatrix& m, size_t count = 1, const std::string& val = "inputString")
{
if (m.empty() || count < 1)
return;
size_t cols = m.front().size() + count;
for (auto& row : m)
row.resize(cols, val);
}


Related Topics



Leave a reply



Submit