How to declare dynamic 2D integer array in C++ - c++

I've a requirement where I need to take input from user and based on the input length of array would be decided. For e.g.
int row, column;
cin>> row>>column;
int matrix[row][column];
However int matrix[row][column] is not working as compiler is giving an error saying
"Expression must have a constant value"
Also, if someone can guide me as how address of matrix[row][column] assigned to pointer. I know how to do it with static array but not dynamic.

To declare 2d dynamic array you will need pointers of pointers
int row, column;
cin>> row>>column;
int** matrix = new int*[row];
for(int i = 0; i < row; ++i)
matrix[i] = new int[column];
This is because arrays are static in c++ and take a fixed position in the memory.lets say the array has 1000 element. when you declare a static array this means that there is 1000 positions in the memory after each other reserved for your array. If you want to add one more item to the array you will add this item in the end of the reserved array, but if that position has some data for something other than the array, this data will be deleted!!
but when you declare it as pointers, you don't store the elements nested in the memory, but you are storing them in different locations, and each location is stored in the array of pointers, and when you add new elements to the array, compiler will search for empty locations in the memory and will store the new elements there.

Using a 2D array to hold a matrix is a bad idea - especially because of the loop for memory allocations.
Use a 1D array of size rows * columns and access elements with y * columns+x, and store it inside and unique_ptr to avoid commons memory management problems.
Here's what I propose:
uint32_t rows, cols;
std::cin >> rows >> cols; // Check rows and cols are actually numbers
std::unique_ptr<int[]> matrix(new int[rows*cols]);

Related

Creating bidimensional array's size with the input values

First of all, happy new year!
So, I'd like to ask if I could use some input values as the size of a bidimensional array, for example:
I'd like to know, if instead of doing this:
const int N = 10;
const int M = 10;
typedef int IntMatrix[N][M];
Let's say that would be the max size of the array I could create, but then the user inputs that the size must have a size of 5x5. I know I could then use 5x5 as a limit when doing stuff, but could I do like the same, but using the input values as the dimension of the Matrix?
Something like:
cin >> N >> M;
And then use that as the MAX size of each dimension.
Thanks for your help!
No. The size of an array must be known at compile time and can not be determined at runtime as described in this tutorial for example. Therefore, the size of the array cannot depend on user input.
What you can do, is allocate an array dynamically and store it's address in a pointer. The size of a dynamic array can be determined at runtime. However, there is a problem. Only the outermost dimension of a dynamically allocated 2D array may be determined at runtime. You have 2 options: Either you allocate a flat array of size NxM where the rows are stored continuously one after the other and you calculate the index using maths. Or, you use an array of pointers and assign each pointer to a dynamically allocated array column. The first option is more efficient.
There is another problem. Dynamic memory management is hard, and it's never a good idea to do it manually even if you know what you're doing. Much less if you don't. There is a container class in the standard library which takes care of memory management of dynamic arrays. It's std::vector. Always use it when you need a dynamic array. Your options stay similar. Either use a flat, NxM size vector, or a vector of vectors.
The array should be dynamically allocatedn because array size should be known at compile-time. You can do this way:
int N,M; // Dimensions
int** intMatrix; // Array of array
std::cin << N << M;
intMatrix = new int*[N]; // Allocate N the row
for(int i=0; i<N; i++){
intMatrix[i] = new int[M]; // For each row, allocate the col
}
// aaaand don't forget to free memory like this:
for(int i=0; i<N; i++){
delete [] intMatrix[i];
}
delete [] intMatrix;

declare and initialize 2d array with unknown size

I take the size of rows n and columns m from the user
I want to make a 2D array (matrix) of the size nxm , initialize it and do some work on it
int main()
{
int m,n;
cin>>m>>n;
const int grow=m;
const int gcol=n;
auto G = new double[grow][gcol](); //GIVES ERROR that grow and gcol must be const
/*int** G = new int*[n];
for (int i = 0; i < n; ++i)
G[i] = new int[n];*/
}
You can always index in a one dimensional array with y * gcol + x to make it effectively work as a two dimensional one. With that you can use a dynamic memory e.g. with a std::vector<double>.
//GIVES ERROR that grow and gcol must be const
No, it does not. Unless your compiler is bad. Read the error again.
It gives an error that gcol must be a constant expression.
You cannot have dynamic arrays of dynamic arrays. It's simply not possible in c++. You can only have dynamic arrays of things that have a static size, known at compile time.
Therefore, you cannot have a 2D array where both dimensions are determined at runtime.
You have 2 alternatives:
Use a dynamic array of pointers to dynamic arrays. Which is what you have there, commented out. A dynamic array of vectors works too.
Use a flat, one dimensional array that contains the rows in succession.
In either case, I recommend using a class to manage the memory. std::vector, perhaps.
Array size is part of the type and needs to be known at compile time. You get it at runtime. Use vectors instead.

How to get the dimensions of a 2d dynamic array of strings in C++?

I have a dynamically populated array of strings in C++:
string** A;
it is populated like this:
A = new string*[size1];
and then:
for (unsigned int i = 0; i < size1; i++)
{
A[i] = new string[size2];
for (unsigned int j = 0; j < size2; j++)
{
A[i][j] = whatever[j];
}
}
elsewhere, I want to find out the dimensions (size1 and size2).
I tries using this:
sizeof(A[i]) / sizeof(A[i][0])
but it doesn't work.
Any ideas ?
Thanks
When you allocate memory via new T[N], the value N is not stored anywhere . If you need to know it later, you will need to keep track of it in your code.
There are pre-existing classes for allocating memory that also remember the length that was allocated. In your code:
vector<vector<string>> A(size1, vector<string>(size2));
// (code to populate...)
then you can access A.size() to get size1, and A[0].size() to get size2.
If the dimensions are known at compile-time you may use array instead of vector.
It is very simple to find the size of a two dimensional (more exactly of one-dimensional dynamically allocated arrays) array. Just declare it like
std::vector<std::vector<std::string>> A;
and use
std::cout << A.size() << std::endl;
As for your approach then you have to store the sizes in some variables when the array is allocated.
If you are learning C++, I would recommend that you learn Classes. With a class you can encapsulate int variables along with your 2D array that you can use to store the dimensions of your array. For example:
class 2Darray{
string **array;
int rows;
int cols;
}
You can then get the dimensions of your 2Darray object anytime by reading these member variables.
vectors will do this for you behind the scenes but its good for you to learn how to do this.
You can't create an array just using pointer operator. Every array is basically a pointer with allocated memory. That's why compiler wants constant before creating array.
Basically; sizeof(A[i]) won't give you the size of array. Because sizeof() function will return the a pointers size which is points to A[i] location. sizeof(A[i]) / sizeof(A[i][1]) will probably give you 1 because you are basically doing sizeof(int)/sizeof(int*)
So you need to store the boundary yourself or use vectors. I would prefer vectors.
Can't get array dimensions through pointer(s)

Declaring array with user-defined size before the main function

I have a an array int matrix[10][10] as well as other arrays with similar size which is declared before the prototype functions and main function. This 2d array is used by all of the functions. However, I need my program to have a function that asks the user the size of the matrix he wants. So, it's gotta be something like this: int matrix[ROWS][COLUMNS]. I know for sure that I can't place the declare the array inside the main function since this array is used by all the other functions. How do I declare this kind of array?
First of all, it is impossible to declare an array with variable sizes, as they are not legal in C++ (although they are legal in C). So you're out of luck here.
Second, you want the declaration before main. Hence, you have to use either
A dynamic array, defined globally like int** matrix; and initialized in main() as
matrix = new int*[ROWS];
for(size_t i = 0 ; i < ROWS; ++i)
matrix[i] = new int[COLS];
then you'd have to release its memory at the end of the day
for(size_t i = 0; i < ROWS; ++i)
delete[] matrix[i];
delete[] matrix;
or
A standard container like std::vector<>
std::vector<int> matrix; // defined globally
and in main() reserve memory for it, like
matrix.reserve(ROWS*COLUMNS); // reserve memory for M rows
Then you'd need to play around with the indexes, so you can map from pairs of indexes to 1D index, i.e. the "logical" element [i][j] is represented by the index i * COLS + j in matrix.
Of course, you could have used a std::vector<std::vector<int>>, however this approach is faster since the memory is guaranteed to be contiguous (same applies to the first example, where you could have used an int* instead).

dynamic allocation of rows of 2D array in c++

In c++, I can create a 2D array with fixed number of columns, say 5, as follows:
char (*c)[5];
then I can allocate memory for rows as follows
c = new char[n][5];
where n can be any variable which can be assigned value even at run time. I would like to know whether and how can I dynamically allocate variable amount of memory to each row with this method. i.e. I want to use first statement as such but can modify the second statement.
Instead of a pointer to an array, you'd make a pointer to a pointer, to be filled with an array of pointers, each element of which is in turn to be filled with an array of chars:
char ** c = new char*[n]; // array of pointers, c points to first element
for (unsigned int i = 0; i != n; ++i)
c[i] = new char[get_size_of_array(i)]; // array of chars, c[i] points to 1st element
A somewhat more C++ data structure would be a std::vector<std::string>.
As you noticed in the comment, dynamic arrays allocated with new[] cannot be resized, since there is no analogue of realloc in C++ (it doesn't make sense with the object model, if you think about it). Therefore, you should always prefer a proper container over any manual attempt at dynamic lifetime management.
In summary: Don't use new. Ever. Use appropriate dynamic containers.
You need to declare c as follows: char** c; then, allocate the major array as follows: c = new char*[n]; and then, allocate each minor array as follows: c[i] = new char[m]
#include <iostream>
using namespace std;
main()
{
int row,col,i,j;
cout<<"Enter row and col\n";
cin>>row>>col;
int *a,(*p)[col]=new (int[row][col]);
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[i][j]=i+j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
cout<<i<<" "<<j<<" "<<p[i][j]<<endl;
//printf("%d %d %d\n",i,j,p[i][j]);
}