Initializing a multi dimensional array in C++ - c++

I recently started programming in C++, I have quite some experience in JAVA programming but I am facing a rather unclear situations whilst trying to initialize multi dimensional arrays in c++.
The code I would use in java would be something like:
int x = 5;
int y = 10;
int array [][] = new int[x][y];
which works fine, I could assign any value to x and y using a scanner or option pane. However (and please bear with me, I am quite new to c++) in c++ I am required to use constants which prevent me from using for example:
int x;
cin >> x;
int y;
cin >> y;
int array [][] = new int[x][y];
I am trying to make a random map generator, eventually i will assign 3d object to positions within the array and design an algorithm to sort all of the objects. However I want the user to be able to specify the size of the grid, specify x and y, the rows and columns.
Any help would be greatly appreciated!
Many thanks in advance.

This record
int array [][] = new int[x][y];
is invalid in C++. If you want to allocate an array in the heap using operator new and the right dimension is not a constant expression then you should write
int x;
cin >> x;
int y;
cin >> y;
int **array = new int *[x];
for ( int i = 0; i < x; i++ ) array[i] = new int[y];
If the right dimension is set by a constant expression then you can write
int x;
cin >> x;
const int y = SomeValue;
int ( *array )[y] = new int [x][y];
Take into account that you could use standard container std::vector instead of a manually allocated array.
For example
std::vector<std::vector<int>> v( x, std::vector<int>( y ) );

There are multiple ways to do this. To create a permanent array on the heap:
int** data = new int*[x];
for(int i = 0; i < x;i++)
{
data[i] = new int[y];
}
To create an array of fixed size on the stack:
int data[5][5];

The dimensions of the array must be known at compile time.
For me this simple code fails to compile due to lack of knowledge of the array size.
int i = 5;
int arr [] = new int[i];
arr[2] = 2;
If you want to use arrays you have two choices, use constants that are known at compile time, or create the array using malloc to reserve memory.
If you are able to use the STL use the vector class.
int i = 5;
vector<int> vec(i);
vec[2] = 2;
Or you could use pointers as shown in 'Vlad from Moscow' or 'user3482801' answers.

Related

How do you allocate memory for a 2D array in C++

hey I want to allocate some memory for a 2D array and free it later in C++
I want to do this as I am getting an Error in my program " EXPRESSION MUST HAVE A CONSTANT VALUE.
int x = height;
int y = width;
int pixelArray[x][y];
Thank you.
I'm using Visual Studio 2013
The naive approach is to allocate one array to contain row pointers, and then allocate every single row, but this can lead to poor performance of your array due to memory locality. It also cannot be used in the same way as a fixed-size 2D array, which is contiguous in memory.
So what you can do is allocate one block of integers to hold all the data, and one array of pointers to index it.
int ** my_array = new int*[ x ];
my_array[0] = new int[ x * y ];
for( int i = 1; i < x; i++ )
{
my_array[i] = my_array[i-1] + y;
}
To clean up, you do this:
delete [] my_array[0];
delete [] my_array;
You should consider wrapping this functionality into a simple class, since it is maintaining more than one pointer.
Since x and y are variables, you have to dynamically allocate the array using new. You can initialize a 2D array as follows:
int ** pixelArray = new int*[x];
for (int i = 0; i < x; i++) {
pixelArray[i] = new int[y];
}
And you dispose of it in the following way:
for (int i = 0; i < x; i++) {
delete[] pixelArray[i];
}
delete[] pixelArray;

cpp two dimensional dynamic array

I'm using c++ and I want to use two dimensional dynamic array. I tried this:
#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
for(int j=0; j<w; j++){
cin>>a[i][j];
}
}
but not worded.
and I tried this:
int *a = new a[size][w];
instead of
int a[size][w];
but not worked!
could you help me plz.
thanks a lot.
The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.
That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:
const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];
Without the typedef, the syntax is a bit more convoluted, but doable:
int (*p)[w] = new int [size][w];
In both cases you would release memory with the same simple statement:
delete [] p;
The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).
For a dynamic sized array you must dynamically allocate it. Instead of
int *a = new a[size][w];
Use
int** a = new int*[size];
for(int i = 0; i < size; i++)
a[i] = new int[w];
OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:
int main() {
const int w = 2;
int size = 10;
int* arr[w];
for (int i = 0; i < w; ++i)
arr[i] = new int[size];
//do whatever with arr..
//std::cout<<arr[0][0];
for (int i = 0; i < w; ++i)
for (int j = 0; j < size; ++j)
std::cout<<arr[i][j];
for (int i = 0; i < w; ++i)
delete[] arr[i];
return 0;
}
You can not do that in c++, please read about dynamic memory allocation
the code below should work
int* twoDimentionalArray = new [size*w]

Can't declare dynamic 2D array in C++ [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 8 years ago.
I've stuck on a problem - I can't declare 2D arrays in C++ using integers, written by user.
This code works fine-
cin>>m>>n;
int *array;
array=new int[m*n];
But I can't make this work -
cin>>m>>n;
int *array;
array=new int[m][n];
Any ideas how i can bypass it?
P.S. the error : cannot convert 'int ()[2]' to 'int' in assignment.
Change
cin>>m>>n;
int *array;
array=new int[m][n];
to
cin>>m>>n;
int **array;
array=new int * [m];
for ( int i = 0; i < m; i++ ) array[i] = new int[n];
array is int * and you try to assign int **... change array to int**.
2D array is actually array of arrays, so you need pointer to pointer.
That's because you can only use new to allocate 1D arrays. In fact, 2D arrays are also 1D arrays, where, in most systems, all rows are simply concatenated. That is called a row-major memory layout.
You can emulate 2D arrays with a 1D array. The index conversion is:
index1 = y * m + x
This also has much better performance than creating one array per row, as recommended in the "duplicate" link or in other answers.
Just as Domi said (but not index1=y*m+x but rather index1=x*n+y to emulate your desired notation):
int *array = new int [m*n];
int get (int x, int y) // emulates array[x][y] for array[m][n]
{
return array[x*n+y];
}
However, I think the real 2-dimensional allocation (as Vlad from Moscow showed you) is slower in creation (and needs a bit more memory), but quicker in accessing. Cause array[x*n+y] == *(array+x*n+y), wether array[x][y] == *(*(array+x)+y), so you have one multiplication less, but one dereferenciation more, in sum I think it's quicker.
You could also create a class:
class array2d
{
private:
int *data;
int mm, nn;
public:
array2d (int m, int n)
{
mm = m;
nn = n;
data = new int [m*n];
}
~array2d ()
{
delete[] data;
}
int *operator[] (int x)
{
return (data+x*nn);
}
};
With it you can use
array2d arr(10,10);
arr[5][7] = 1;
You can do this:
typedef int RowType[n];
RowType *array = new RowType[m];
doStuffWith(array[y][x]);
Or, even shorter (but harder to remember):
int (*array)[n] = new (int[m][n]);
Edit:
There is a catch in C++ that array sizes must be constant for the new operator, so you can only do this if n is const. This is not a problem in C (and the reason I forgot about this), so the following works even if n and m are not const:
RowType *array = (RowType*)malloc(m * sizeof(RowType));
Of course, you can work around this restriction in C++ by doing this, which works even if both m and n are dynamic:
RowType *array = (RowType*)new int[m * n];
The typedef free version would be this:
int (*array)[n] = (int (*)[n])new int[m *n];
Firstly I suggest you should use std::vector to avoid memory allocation / deallocation issues.
In case you want an array implementation, then you can declare array as a pointer to pointer to int.
cin >> m >> n;
int** array = new int* [m];
for ( int I = 0; I < m; I++ ) {
array[I] = new int[n];
}

C++ Dynamic Array 1 dimension non dynamic

Been awhile since I've programmed in C++ however I have a slight problem that I'm trying to figure out.
Is it possible to make a 2 by 2 dynamic array where 1 dimension is not dynamic?
For example
array[2][Dynamic]?
It seems like a waste to make array[dynamic][dynamic] and when I only need to use the first [0][dynamic] and second [1][dynamic] values.
Should I use another data structure?
Thanks.
Arrays and pointers are basically equivalent, so you can achieve this with an array of pointers:
int* array[2];
array[0] = new int[x];
array[1] = new int[y];
You can still access it as you would multidimensional array:
array[0][x-1] = z;
This works in C++11:
std::array<std::vector<MyClass>,2> arr;
Or you could use a c-style array of vectors
std::vector<MyClass> arr[2];
Sure but it has to be dynamic in the first dimension.
Like this for instance
typedef int two_int_array[2];
two_int_array* a = new two_int_array[n];
for (int i = 0; i < n; ++i)
{
a[i][0] = 1;
a[i][1] = 2;
}
Of course the better way in general is to use vectors. Since you can't have a vector of arrays, a vector of structs might be better for your case.
struct two_int_struct
{
int value[2];
};
std::vector<two_int_struct> a(n);
for (int i = 0; i < n; ++i)
{
a[i].value[0] = 1;
a[i].value[1] = 2;
}

Initialization of 2D array with dynamic number of rows and fixed number of columns. C++

I'm having problem with creating my 2D dynamic array in C++. I want it to have dynamic number (e.g. numR) of "rows" and fixed (e.g. 2) number of "columns".
I tried doing it like this:
const numC = 2;
int numR;
numR = 10;
double *myArray[numC];
myArray = new double[numR];
Unfortunately, it doesn't work. Is it possible to do it in such a way?
Of course I could use double **myArray and initialize it as if both dimensions are dynamic (with numC used as limiter in loop) but I would like to avoid it if possible.
Thanks in advance.
Is it possible to do it in such a way?
Yes:
double (*myArray)[numC] = new double[numR][numC];
// ...
delete[] myArray;
This may look a little unusual, but 5.3.4 ยง5 clearly states:
the type of new int[i][10] is int (*)[10]
Note that many programmers are not familiar with C declarator syntax and will not understand this code. Also, manual dynamic allocation is not exception safe. For these reaons, a vector of arrays is better:
#include <vector>
#include <array>
std::vector<std::array<double, numC> > vec(numR);
// ...
// no manual cleanup necessary
Replace std::array with std::tr1::array or boost::array, depending on your compiler.
Why not use a std::vector, and take advantage of its constructor:
std::vector<std::vector<int> > my2Darray(2, std::vector<int>(10));
my2Darray[0][0] = 2;
There needs to be a loop since you need to create an array for every column.
I think what you're after is:
double *myArray[numC];
for (int i = 0; i < numC; i++) {
myArray[i] = new double[numR];
}
// some code...
// Cleanup:
for (int i = 0; i < numC; i++) {
delete [] myArray[i];
}
This declares an array of pointers (to double) with numC elements, then creates an array of doubles with numR elements for each column in myArray. Don't forget to release the memory when you're done with it or you'll have memory leaks.
Your indexes should be row, then column.
double** myArray = new double*[numR];
for( unsigned int i = 0; i < numR; i++ ) {
myArray[i] = new double[numC];
}
Access row 2, column 5:
myArray[2][5];