C ++ declares an array of arrays without knowing the size

I have to declare an array of arrays or a multidimensional array without knowing the size. I want to do something similar, which I do in this case with simple arrays:

int *array; cin >> size; array = new int[size]; 

Maybe I can do a loop to initialize a pointer pointer like this:

 int **array; cin >> rows >> col; array = new *int[rows] for (int i = 0; i < rows; ++i) array[i] = new int[col]; 

But I prefer not to do this if a better solution is possible.

+6
source share
4 answers

Why not use std :: vector?

 std::vector<std::vector<int> > array; 

If you do not want to use an array of pointers, you can use one large array that you allocate dynamically after getting the size and accessing it as an array of strings.

 int rows = 10; int columns = 20; int* array = new int[rows * columns]; for (int count = 0; count < rows; count++) { int* row = &array[count * columns]; for (int inner_count = 0; inner_count < columns; inner_count++) { int* element = &row[inner_count]; //do something } } delete [] array; 
+5
source

You pretty much have to go with the loop version. You can make a small improvement, which should highlight one large block, and then create your own int* index in it:

 int **array; int *storage; cin >> rows >> col; array = new *int[rows]; storage = new int[rows*col]; for (int i = 0; i < rows; ++i) array[i] = storage + col * i; 

This property has the nice property that you can use the syntax array[i][j] to access the array.

+1
source

If you don't care, you might have a little more convenience if you have an assistant

 template <typename T> struct C3DArray { vector<vector<vector<T>>> m; C3DArray(int size_x, int size_y, int size_z) : m(make(T(), size_z, size_y, size_x)) { } template <typename U> static std::vector<U> make(U v, size_t n) { return { n, std::move(v) }; } template <typename U, typename... Dim> static auto make(U v, size_t n, Dim... other) -> std::vector<decltype(make(v, other...))> { return { n, make(v, other...) }; } }; 

It uses variations. Use it like this:

 C3DArray<int> arr(3,4,20); 
0
source

You can use a single std :: vector to contain the entire two-dimensional array and transfer it to the class to hide the details. In this example, it uses the data( row, col ) member function data( row, col ) , which returns a reference to the element in row and col . I included an example of a 2-dimensional int matrix, where each record in the array is initialized by the product of its row and col . When an instance of this class goes out of scope, the default destructor will be called and free up memory, so you don't need to forget to call delete [] to free up memory. All matrix elements will be contiguous in memory, this is caching and should give you good performance.

 #include <iostream> #include <vector> #include <stdexcept> template <typename T> class matrix { std::vector<T> data_; public: size_t const rows_; size_t const cols_; matrix(size_t rows, size_t cols) : rows_(rows) , cols_(cols) , data_( rows * cols ) {} T& data( size_t row, size_t col ) { if (row > rows_ || col > cols_) throw std::out_of_range("matrix"); return data_[ row * cols_ + col ]; } }; int main( int argc, char** argv ) { matrix<int> array(100,100); for(size_t r=0; r < array.rows_; ++r) { for(size_t c=0; c < array.cols_; ++c) { array.data(r,c) = r * c; } } std::cout << "8 x 7 = " << array.data(8,7) << std::endl; return 0; // array goes out of scope here, memory released automatically } 

When you run this, you will get

 8 x 7 = 56 
0
source

Source: https://habr.com/ru/post/927405/


All Articles