# Visual C++ & C++ Programming > C++  (Non Visual C++ Issues) >  move data from a 2D vector into a 3D vector, three times. the sizes of the 2D vector

## maninthemiddle

I am collecting numerical data into a 2D vector. At the end of every cycle that 2D vector dumps into a 3D vector. The size of the 2D vector varies.

I am getting a vector overload during the use of the 3D vector (only when the rows and columns aren't the same as the previous entry).

I have successfully completed this exact challenge using a changing 1D that goes into a 2D with no errors. So, I am suspicious that my 2D vector is not being cleared properly, using clear(). Perhaps there is an additional built-in function within C++?

After several attempts searching on google and SOF, I am amazed that I can't find someone who has asked how to do this.

It seemes like an extremely common necessity.



```
#include <iostream>
#include <vector>
#include <random>

int main()
{
	// vector init
	std::vector<std::vector<int>> vec_input_ctrl;
	std::vector <int> vec_ctrl_values;
	std::vector<std::vector<int>> vec_collected_values;
	std::vector<std::vector<std::vector<int>>> vec_collected_values_3D;

	// random number generatior
	std::random_device random_device_01;
	std::mt19937 randgen_01(random_device_01());

	// variable init
	int var_int;
	int column_count = 0;
	int row_count = 0;
	int cycle_count = 5;

	// 3D loop
	for (int var_cycle = 0; var_cycle < cycle_count; var_cycle++)
	{
		std::uniform_int_distribution<> columns(10, 20);
		column_count = columns(randgen_01);

		std::uniform_int_distribution<> rows(3, 10);
		row_count = rows(randgen_01);

		// verify input
		std::cout << "verify input" << std::endl;
		for (int var_create_vector_a = 0; var_create_vector_a < column_count; var_create_vector_a++)
		{
			vec_input_ctrl.emplace_back(column_count);
			for (int var_output_vector = 0; var_output_vector < row_count; var_output_vector++)
			{
				vec_input_ctrl[var_create_vector_a].push_back(0);
				std::cout << vec_input_ctrl[var_create_vector_a][var_output_vector] << " ";
			}
			std::cout << std::endl;
		}
		std::cout << std::endl << std::endl;

		// 2D loop
		for (int var_create_vector_a = 0; var_create_vector_a < column_count; var_create_vector_a++)
		{
			// create blank 1D vector
			std::cout << "create blank 1D vector" << std::endl;
			for (int var_create_vector_b = 0; var_create_vector_b < vec_input_ctrl[var_create_vector_a].size(); var_create_vector_b++)
			{
				vec_ctrl_values.push_back(vec_input_ctrl[var_create_vector_a][var_create_vector_b]);
				std::cout << vec_ctrl_values[var_create_vector_b] << " ";
			}
			std::cout << std::endl;

			// randomly adjust values in 1D vector
			std::cout << "randomly adjust values in 1D vector" << std::endl;
			for (int var_adjust_vector = 0; var_adjust_vector < row_count; var_adjust_vector++)
			{
				std::uniform_int_distribution<> rand_amount(0, 9);
				var_int = rand_amount(randgen_01);

				vec_ctrl_values[var_adjust_vector] = var_int;
				std::cout << vec_ctrl_values[var_adjust_vector] << " ";
			}
			std::cout << std::endl;

			// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
			// verify the vector size inside the 2D loop
			if (vec_collected_values.size() > 0)
			{
				std::cout << "vec_collected_values 1D size inside the 2D loop is: " << vec_collected_values.size() << std::endl;
				if (vec_collected_values[0].size() > 0) std::cout << "vec_collected_values 2D size inside the 2D loop is: " << vec_collected_values[0].size() << std::endl;
				else std::cout << "vec_collected_values 2D size inside the 2D loop is empty" << std::endl;
			}
			else std::cout << "vec_collected_values 2D size inside the 1D loop is empty" << std::endl;
			// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

			// move 1D vector into 2D vector
			std::cout << "move 1D vector into 2D vector" << std::endl;
			vec_collected_values.emplace_back(row_count);
			for (int var_output_vector = 0; var_output_vector < row_count; var_output_vector++)
			{
				vec_collected_values[var_create_vector_a][var_output_vector] = vec_ctrl_values[var_output_vector];
				std::cout << vec_collected_values[var_create_vector_a][var_output_vector] << " ";
			}

			// resets
			vec_ctrl_values.clear();
			std::cout << std::endl << std::endl;
		}

		// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
		// verify the vector size
		if (vec_collected_values.size() > 0)
		{
			std::cout << "vec_collected_values 1D size after the 2D loop is: " << vec_collected_values.size() << std::endl;
			if (vec_collected_values[0].size() > 0) std::cout << "vec_collected_values 2D size after the 2D loop is: " << vec_collected_values[0].size() << std::endl;
			else std::cout << "vec_collected_values 2D size after the 2D loop is empty" << std::endl;
		}
		else std::cout << "vec_collected_values 2D size after the 1D loop is empty" << std::endl;
		// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

		// verify 2D vector
		std::cout << "verify 2D vector" << std::endl;
		for (int var_output_vector_a = 0; var_output_vector_a < column_count; var_output_vector_a++)
		{
			for (int var_output_vector_b = 0; var_output_vector_b < row_count; var_output_vector_b++)
			{
				std::cout << vec_collected_values[var_output_vector_a][var_output_vector_b] << " ";
			}
			std::cout << std::endl;
		}
		std::cout << std::endl << std::endl;

		// move 2D vector into 3D vector
		std::cout << "move 2D vector into 3D vector" << std::endl;
		for (int var_output_vector_a = 0; var_output_vector_a < column_count; var_output_vector_a++)
		{
			vec_collected_values_3D.emplace_back(column_count, std::vector <int>(row_count));
			for (int var_output_vector_b = 0; var_output_vector_b < row_count; var_output_vector_b++)
			{
				vec_collected_values_3D[var_cycle][var_output_vector_a][var_output_vector_b] = vec_collected_values[var_output_vector_a][var_output_vector_b];
				std::cout << vec_collected_values_3D[var_cycle][var_output_vector_a][var_output_vector_b] << " ";
			}
			std::cout << std::endl;
		}
		vec_collected_values[row_count].clear();
		vec_collected_values.clear();

		// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
		// verify the vector size
		if (vec_collected_values.size() > 0)
		{
			std::cout << "vec_collected_values 1D size after.clear() the 2D loop is: " << vec_collected_values.size() << std::endl;
			if (vec_collected_values[0].size() > 0) std::cout << "vec_collected_values 2D size after.clear() the 2D loop is: " << vec_collected_values[0].size() << std::endl;
			else std::cout << "vec_collected_values 2D size after.clear() the 2D loop is empty" << std::endl;
		}
		else std::cout << "vec_collected_values 2D size after.clear() the 1D loop is empty" << std::endl;
		// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

		std::cout << std::endl << std::endl;
		std::cout << "end of 2D loop #" << var_cycle << std::endl;
		std::cout << std::endl << std::endl;
		std::cout << "end of 2D loop #" << var_cycle << std::endl;
		std::cout << std::endl << std::endl;
		std::cout << std::endl << std::endl;
	}

	// verify 3D vector
	std::cout << "verify 3D vector" << std::endl;
	for (int var_cycle = 0; var_cycle < cycle_count; var_cycle++)
	{
		std::cout << "vec_collected_values_3D #" << var_cycle << std::endl;
		for (int var_output_vector_a = 0; var_output_vector_a < column_count; var_output_vector_a++)
		{
			for (int var_output_vector_b = 0; var_output_vector_b < row_count; var_output_vector_b++)
			{
				std::cout << vec_collected_values_3D[var_cycle][var_output_vector_a][var_output_vector_b] << " ";
			}
			std::cout << std::endl;
		}
		vec_collected_values.clear();
		std::cout << std::endl << std::endl;
	}
	return 0;
}
```


linki 
https://godbolt.org/z/G6q5rac5d

----------


## 2kaud

You don't show the definition of the 2d and 3d  vectors or how they are created - but the emplace() doesn't look right for a 3d-array...

----------


## maninthemiddle

Forgive me, I pasted a sniplet of my code from a 2000 line program. I didn't want to cut and paste more than was necessary to understand the problem. So instead of pasting more of what might cause confusion, I provided a minialized example of what I am doing. This is the line where the error happens: vec_final_2D_collecter[var_move_vector_a].push_back(vec_collected_values_01[var_move_vector_a][var_move_vector_b]); 

----------


## maninthemiddle

if you move the following lines above the main for loop, eveything works fine. Hence, the program the logic of the program is sound, except when the columns and rows change every cycle
std::uniform_int_distribution<> columns(10, 20);
column_count = columns(randgen_01);

std::uniform_int_distribution<> rows(3, 10);
row_count = rows(randgen_01);

----------


## 2kaud

As a refactor into functions etc, consider:



```
#include <iostream>
#include <vector>
#include <random>

using Vec1d = std::vector<int>;
using Vec2d = std::vector<Vec1d>;
using Vec3d = std::vector<Vec2d>;

// Random number generator
std::mt19937 randgen_01(std::random_device {}());

void zero2d(Vec2d& vec_input_ctrl, size_t column_count, size_t row_count) {
	std::cout << "Zero 2d vec\n";

	vec_input_ctrl.resize(column_count);

	for (size_t var_create_vector_a {}; var_create_vector_a < column_count; ++var_create_vector_a) {
		vec_input_ctrl[var_create_vector_a].resize(row_count);

		for (size_t var_output_vector {}; var_output_vector < row_count; ++var_output_vector)
			vec_input_ctrl[var_create_vector_a][var_output_vector] = 0;
	}

	std::cout << "\n\n";
}

void set1d(const Vec2d& vec_input_ctrl, Vec1d& vec_ctrl_values, size_t var_create_vector_a, size_t row_count) {
	static std::uniform_int_distribution<> rand_amount(0, 9);

	std::cout << "Create blank 1D vector\n";

	for (size_t var_create_vector_b {}; var_create_vector_b < vec_input_ctrl[var_create_vector_a].size(); ++var_create_vector_b)
		vec_ctrl_values.push_back(vec_input_ctrl[var_create_vector_a][var_create_vector_b]);

	// Randomly adjust values in 1D vector
	std::cout << "\nRandomly adjust values in 1D vector\n";

	for (size_t var_adjust_vector {}; var_adjust_vector < row_count; ++var_adjust_vector)
		vec_ctrl_values[var_adjust_vector] = rand_amount(randgen_01);
}

void verColl(const Vec2d& vec_collected_values) {
	if (vec_collected_values.size() > 0) {
		std::cout << "vec_collected_values 1D size inside the 2D loop is: " << vec_collected_values.size() << '\n';

		if (vec_collected_values[0].size() > 0)
			std::cout << "vec_collected_values 2D size inside the 2D loop is: " << vec_collected_values[0].size() << '\n';
		else
			std::cout << "vec_collected_values 2D size inside the 2D loop is empty" << '\n';
	} else
		std::cout << "vec_collected_values 2D size inside the 1D loop is empty" << '\n';
}

void mov1d2d(Vec2d& vec_collected_values, const Vec1d& vec_ctrl_values, size_t var_create_vector_a, size_t row_count) {
	Vec1d d1(row_count);

	vec_collected_values.push_back(d1);
	std::cout << "Move 1D vector into 2D vector\n";

	if (vec_collected_values.size() < var_create_vector_a) {
		std::cout << "ERROR 2d. Expected " << var_create_vector_a << " but got " << vec_collected_values.size() << '\n';
		std::cin.get();
	}

	for (size_t var_output_vector {}; var_output_vector < row_count; ++var_output_vector)
		vec_collected_values[var_create_vector_a][var_output_vector] = vec_ctrl_values[var_output_vector];
}

void ver2d(const Vec2d& vec_collected_values) {
	std::cout << "Verify 2D vector\n";

	for (size_t var_output_vector_a {}; var_output_vector_a < vec_collected_values.size(); ++var_output_vector_a) {
		for (size_t var_output_vector_b {}; var_output_vector_b < vec_collected_values[var_output_vector_a].size(); ++var_output_vector_b)
			std::cout << vec_collected_values[var_output_vector_a][var_output_vector_b] << " ";

		std::cout << '\n';
	}

	std::cout << "\n\n";
}

void mov2d3d(Vec3d& vec_collected_values_3D, const Vec2d& vec_collected_values, size_t column_count, size_t row_count, size_t var_cycle) {
	Vec2d d2(column_count);

	std::cout << "Move 2D vector into 3D vector\n";
	vec_collected_values_3D.push_back(d2);

	if (vec_collected_values_3D.size() < var_cycle) {
		std::cout << "ERROR 3d. Expected 3d size " << var_cycle << " got " << vec_collected_values_3D.size() << '\n';
		std::cin.get();
	}

	for (size_t var_output_vector_a {}; var_output_vector_a < column_count; ++var_output_vector_a) {
		vec_collected_values_3D[var_cycle][var_output_vector_a].resize(row_count);

		for (size_t var_output_vector_b {}; var_output_vector_b < row_count; ++var_output_vector_b)
			vec_collected_values_3D[var_cycle][var_output_vector_a][var_output_vector_b] = vec_collected_values[var_output_vector_a][var_output_vector_b];
	}
}

void ver3d(const Vec3d& vec_collected_values_3D) {
	std::cout << "Verify 3D vector\n";

	for (size_t var_cycle {}; var_cycle < vec_collected_values_3D.size(); ++var_cycle) {
		std::cout << "Vec_collected_values_3D #" << var_cycle << '\n';

		for (size_t var_output_vector_a {}; var_output_vector_a < vec_collected_values_3D[var_cycle].size(); ++var_output_vector_a) {
			for (size_t var_output_vector_b {}; var_output_vector_b < vec_collected_values_3D[var_cycle][var_output_vector_a].size(); ++var_output_vector_b)
				std::cout << vec_collected_values_3D[var_cycle][var_output_vector_a][var_output_vector_b] << " ";

			std::cout << '\n';
		}

		std::cout << "\n\n";
	}
}

int main() {
	const int cycle_count { 5 };

	Vec3d vec_collected_values_3D;
	size_t column_count {};
	size_t row_count {};

	// 3D loop
	for (size_t var_cycle {}; var_cycle < cycle_count; ++var_cycle) {
		static std::uniform_int_distribution<> columns(10, 20);
		static std::uniform_int_distribution<> rows(3, 10);

		Vec2d vec_collected_values;
		Vec2d vec_input_ctrl;

		column_count = columns(randgen_01);
		row_count = rows(randgen_01);

		// Create 0 2d vector
		zero2d(vec_input_ctrl, column_count, row_count);

		// 2D loop
		for (size_t var_create_vector_a {}; var_create_vector_a < column_count; ++var_create_vector_a) {
			Vec1d vec_ctrl_values;

			// Create 1D vector
			set1d(vec_input_ctrl, vec_ctrl_values, var_create_vector_a, row_count);

			// Verify the vector size inside the 2D loop
			verColl(vec_collected_values);

			// Move 1D vector into 2D vector
			mov1d2d(vec_collected_values, vec_ctrl_values, var_create_vector_a, row_count);

			std::cout << "\n\n";
		}

		// Verify the vector size
		verColl(vec_collected_values);

		// Verify 2D vector
		ver2d(vec_collected_values);

		// Move 2D vector into 3D vector
		mov2d3d(vec_collected_values_3D, vec_collected_values, column_count, row_count, var_cycle);

		std::cout << "\n\nEnd of 2D loop #" << var_cycle << "\n\n\n";
	}

	// Verify 3D vector
	ver3d(vec_collected_values_3D);
}
```

which runs OK

----------


## 2kaud

As a second refactor consider - which is now much more readable/understanding and uses range-for loops etc so that the size of the vectors etc doesn't need to be known except when creating. Also note that std::vector supports = so a vector can be assigned to another vector (it even works for 2d etc):



```
#include <iostream>
#include <vector>
#include <random>

using Vec1d = std::vector<int>;
using Vec2d = std::vector<Vec1d>;
using Vec3d = std::vector<Vec2d>;

// Random number generator
std::mt19937 randgen_01(std::random_device {}());

Vec2d zero2d(size_t column_count, size_t row_count) {
	const Vec2d vec_input_ctrl(column_count, Vec1d(row_count));

	std::cout << "Zero 2d vector\n";
	return vec_input_ctrl;
}

Vec1d set1d(size_t sz) {
	static std::uniform_int_distribution<> rand_amount(0, 9);

	Vec1d vec_ctrl_values(sz);

	std::cout << "\nRandomly adjust values in 1D vector\n";
	for (auto& e : vec_ctrl_values)
		e = rand_amount(randgen_01);

	return vec_ctrl_values;
}

void mov1d2d(Vec2d& vec_collected_values, const Vec1d& vec_ctrl_values) {
	std::cout << "Move 1D vector into 2D vector\n";
	vec_collected_values.push_back(vec_ctrl_values);
}

void ver2d(const Vec2d& vec_collected_values) {
	for (const auto& rc : vec_collected_values) {
		for (const auto& rw : rc)
			std::cout << rw << ' ';

		std::cout << '\n';
	}

	std::cout << "\n\n";
}

void mov2d3d(Vec3d& vec_collected_values_3D, const Vec2d& vec_collected_values) {
	std::cout << "Move 2D vector into 3D vector\n";
	vec_collected_values_3D.push_back(vec_collected_values);
}

void ver3d(const Vec3d& vec_collected_values_3D) {
	std::cout << "Verify 3D vector\n";

	for (size_t var_cycle {};  const auto& v2d : vec_collected_values_3D) {
		std::cout << "Vec_collected_values_3D #" << var_cycle++ << '\n';
		ver2d(v2d);
	}
}

int main() {
	const int cycle_count { 5 };

	Vec3d vec_collected_values_3D;

	// 3D loop
	for (size_t var_cycle {}; var_cycle < cycle_count; ++var_cycle) {
		static std::uniform_int_distribution<> columns(10, 20);
		static std::uniform_int_distribution<> rows(3, 10);

		const auto column_count { columns(randgen_01) };
		const auto row_count { rows(randgen_01) };

		Vec2d vec_collected_values;

		// 2D loop
		for (auto& vc : zero2d(column_count, row_count)) {
			mov1d2d(vec_collected_values, set1d(vc.size()));
			std::cout << "\n\n";
		}

		std::cout << "Verify 2D vector\n";
		ver2d(vec_collected_values);
		mov2d3d(vec_collected_values_3D, vec_collected_values);

		std::cout << "\n\nEnd of 2D loop #" << var_cycle << "\n\n\n";
	}

	ver3d(vec_collected_values_3D);
}
```

----------


## wolle

> I am collecting numerical data into a 2D vector. At the end of every cycle that 2D vector dumps into a 3D vector. The size of the 2D vector varies.


Rather than build the two multidimensional vectors, you could use two one-dimensional vectors together with index mapping functions. As of C++ 23, this approach has standard support by std::mdspan, but there is no reason to wait.

I imagine one of the index functions will map from the one-dimensional index of what was the 2D vector onto the one-dimensional index of what was the 3D vector. It may even be possible to replace the 2D and 3D vectors with a single one-dimensional vector. You would use two different multidimensional views of the same 1D vector.

----------


## 2kaud

And for a 3rd refactor which again simplifies the code considerably, consider:



```
#include <iostream>
#include <vector>
#include <random>

using Vec1d = std::vector<int>;
using Vec2d = std::vector<Vec1d>;
using Vec3d = std::vector<Vec2d>;

std::mt19937 rng(std::random_device {}());

Vec1d create1d(size_t sz) {
	static std::uniform_int_distribution<> rand_amount(0, 9);

	Vec1d v1d(sz);

	for (auto& e : v1d)
		e = rand_amount(rng);

	return v1d;
}

Vec2d create2d() {
	static std::uniform_int_distribution<size_t> columns(10, 20);
	static std::uniform_int_distribution<size_t> rows(3, 10);

	const auto column_count { columns(rng) };
	const auto row_count { rows(rng) };

	Vec2d v2d;

	for (size_t c {}; c < column_count; ++c)
		v2d.push_back(create1d(row_count));

	return v2d;
}

Vec3d create3d(size_t cycle_count) {
	Vec3d vec3d;

	for (size_t var_cycle {}; var_cycle < cycle_count; ++var_cycle)
		vec3d.push_back(create2d());

	return vec3d;
}

void display1d(const Vec1d& v1d) {
	for (const auto& rw : v1d)
		std::cout << rw << ' ';

	std::cout << '\n';
}

void display2d(const Vec2d& v2d) {
	for (const auto& rc : v2d)
		display1d(rc);

	std::cout << "\n\n";
}

void display3d(const Vec3d& v3d) {
	std::cout << "Verify 3D vector\n";

	for (size_t var_cycle {};  const auto& v2d : v3d) {
		std::cout << "Vec_collected_values_3D #" << ++var_cycle << '\n';
		display2d(v2d);
	}
}

int main() {
	constexpr size_t cycle_count { 5 };
	const auto vec3d { create3d(cycle_count) };

	display3d(vec3d);
}
```

This is now module,readable and can be easily modified for future requirements.

----------


## 2kaud

> As of C++ 23, this approach has standard support by std::mdspan, but there is no reason to wait.


Seems to be a nice feature, But as of 29 Dec 2022 isn't supported by any compiler...

Also note that this implementation requires the change to the comma operator within [] to be implemented as array[i, j] is supported meaning for c-style array carray[i][j] and not evaluate i then evaluate j and use the result of j as would be the previous norm.

https://www.open-std.org/jtc1/sc22/w...21/p2128r6.pdf
Currently, this has only been implemented by Clang and GCC.

----------


## wolle

> Seems to be a nice feature, But as of 29 Dec 2022 isn't supported by any compiler...


I know. The std::mdspan is a C++ 23 feature. What I mean is that the principle it represents is already available.

----------


## wolle

> This is now module,readable and can be easily modified for future requirements.


The 3D vector looks like a 1D vector of random-sized 2D vectors filled with random one-digit integers.

Another natural C++ representation would be to keep the 1D vector but encapsulate the 2D vector as a struct/class. Perhaps one could even populate the entire data structure (with random one-digit integers) upon initialization.

----------


## wolle

Assuming the OP wants a vector of random-sized matrices filled with random integers, this is my take. The matrix implementation follows the std::mdspan philosophy,



```
#include <iostream>
#include <vector>
#include <random>

template<typename T>
class Matrix2d { // simple 2D matrix implementation
public:
	Matrix2d(int rows, int cols) : r_(rows), c_(cols), d_(std::vector<T>(rows* cols, {})) {}

	int rows() const { return r_; }
	int cols() const { return c_; }

	T& operator() (int row, int col) { return d_[c_ * row + col]; }   // write element
	T operator() (int row, int col) const { return d_[c_ * row + col]; }   // read element

	auto begin() { return d_.begin(); }   // iterators for sequential access
	auto end() { return d_.end(); }   // that enables use of for-each

private:
	int r_, c_;
	std::vector<T> d_;
};

inline auto& rng() {   // randomly seeded random number generator (is a Singleton)
	static std::mt19937 rng(std::random_device{}());
	return rng;
}

void test() {
	using Matrix = Matrix2d<int>;	// 2D matrix holding ints
	std::vector<Matrix> vec3d; // vector of matrices

		// initialize vec3d
	const int cycle_count = 5;
	std::uniform_int_distribution rowDistr(3, 10);
	std::uniform_int_distribution colDistr(10, 20);
	std::uniform_int_distribution amountDistr(0, 9);
	for (int i = 0; i < cycle_count; ++i) {
		Matrix m(rowDistr(rng()), colDistr(rng()));   // random size matrix
		for (auto& e : m) e = amountDistr(rng());   // filled with random elements
		vec3d.emplace_back(m);
	}

		// print vec3d
	for (const auto& m : vec3d)  {   // all matrices
		std::cout << "--- " << m.rows() << "," << m.cols() << " ---" << std::endl;
		for (int r = 0; r < m.rows(); ++r) {
			for (int c = 0; c < m.cols(); ++c) {
				std::cout << m(r, c) << " ";
			}
			std::cout << std::endl;
		}
	}
}
```

----------

