0

I had been trying to allocate dynamic memory for a two-dimensional array. After searchin a lot I've found a code that looks easier than others still I'm unable to understand each and every detail of it. Can someone explain me how does the following code assigns memory to the array dynamically. Really looking forward for help and sorry but I'm new to C++ and want to learn it.

void main()
{
int m,n;
cin>>m;
cin>>n;
//Allocate
int *a = new int[m*n];
//Use a[m][n]
for( int i = 0 ; i < m ; i++)
        for ( int j = 0 ; j < n ; j++)
                 a[i*n + j] = 1;
}
Ayse
  • 2,676
  • 10
  • 36
  • 61
  • 4
    If you're using C++ then use proper C++ types for arrays, e.g. `std::vector` or `std::array` rather than C-style memory allocations. – Paul R Jul 30 '13 at 09:55
  • 1
    This is actually a one dimensional array that has the length of row*columns. This is quite common in image processing. But the array is indexed as if it were a m * n array. where m is the number of rows and n the number of columns. Therefore i * n puts the index on the i row and you have to `+ j` to get the right column aswell. – hetepeperfan Jul 30 '13 at 10:01

6 Answers6

3

The code just uses a single memory block to represent all elements, so to access a sample ( i, j ) it needs to calculate the index being i * num_rows + j (or num_colums depending how you look at it).

But as commented, don't use new int...., use something like

std::vector< int > a( m * n );
stijn
  • 34,664
  • 13
  • 111
  • 163
1

First, let me point out that this is not a two-dimensional array, but rather a one-dimensional one. You can see that int* a = new int[ m*n ] allocates an array for integers of size m*n.

To obtain a two-dimensional array, you might use int** a = new int*[m]. Note the two asterisks (*) that are used here. Having allocated the "first" dimension of the array, you now have to allocate the second one via:

for( int i = 0; i < m; i++ )
{
   a[i] = new int[n];
}

Afterwards, you can loop over m and n and use a[i][j] to access the array contents.

Using the STL in C++, you can obtain two-dimensional arrays by using a two-dimensional vector, like so:

std::vector< std::vector<int> > array( rows,
                                       std::vector<int>( columns ) );

This would allocate a two-dimensional vector containing integers, with rows elements in the first dimension and columns elements in the second dimension. Such use is sometimes frowned upon, but std::vector manages memory for your, which might be nice.

Gnosophilon
  • 1,340
  • 7
  • 24
1

For the memory it doesn't matter what kind of arrays you have they are all stored as one block of memory, those can the visualised as an 1d array.

In this example, since you want to cave an m x n array you alocate a block of m*n size. The difference between this way and the others is that now you have to acess your array as 1d.

For exemple having the follwoing 2d array:

1 2 3
4 5 6
7 8 9

It will be stored in the memory as follows:

1 2 3 4 5 6 7 8 9

I think you can see the pattern: in order to acces a[i][j] from your 2d array, the 1d equivalent would be a[i*dim+j] where dim is the length of your row.

The way you access your array depends solely on the way you allocate it. In order to be able to acces you elements directly as arr[i][j] you have to allocate the memory ass follows:

int **arr = new int *[n];
for (int i=0; i<n; i++)
     arr[i] = new int [m];

This will create an nxm array.

Alexandru Barbarosie
  • 2,952
  • 3
  • 24
  • 46
1

First of all, what you're doing, is adding 1 to different slots of a ONE-dimensional array.

Here's a commented version of your code:

int *a = new int[m*n];  // declares a pointer a, that points to a newly 
                        // allocated space on the heap, for an array of size m*n.


for( int i = 0 ; i < m ; i++)        // loop through m number of times
    for ( int j = 0 ; j < n ; j++)   // loop through n number of times PER m
             a[i*n + j] = 1;         // assigns 1 to a spot [i*n + j]

THIS is how you make a dynamic 2D array (in other words, array of pointers to arrays):

const int sizeX = 10;
const int sizeY = 5;

int** arrayOfPointers = new int*[sizeX];
for(int i = 0; i < sizeX; i++)
    arrayOfPointers[i] = new int[sizeY];

Then, you can add multiple elements to that array using a double loop (NOT TESTED):

for(int i = 0 ; i < sizeY ; i++)        // loop through all the rows
    for (int j = 0 ; j < sizeX ; j++)   // loop through all columns for row i
         arrayOfPointers[i][j] = i*j; // assigns i*j to a spot at row i, column j

This is how you can print out the contents of the 2D array:

for(int i = 0 ; i < sizeY ; i++) { 

    for (int j = 0 ; j < sizeX ; j++)   
         cout << arrayOfPointers[i][j];

    cout << endl; // go to the next line when the row is finished

}
Oleksiy
  • 37,477
  • 22
  • 74
  • 122
1

Despite what Paul R said and which I fully support, the comment in the code above is wrong, you cannot use a[m][n] for proper addressing of an array that has been allocated as one dimensional memory.

what you can do, if you really must work without using C++ standard containers like vector or array is to allocate the full block and then store addresses to the start of the rows

int** createTwoDimMatrix(unsinged int rows, unsigned int columns)
{
    int** rowAdressTable = new int*[rows];
    int*  baseMemory = new int[rows*columns];

    //fill the rowAddressTable
    for(unsinged int r=1; r<rows; ++r)
    {
         rowAdressTable[r] = rowsAdressTable[r-1]+columns*sizeof(int)
    }
    return rowAdressTable;
}

But let me repeat: Please, consider using C++ containers

ogni42
  • 1,232
  • 7
  • 11
-1

Dynamic is like int *p = new int [10][10] then *(p+(i*noofcols)+j) gives value

Xperiaz X
  • 216
  • 1
  • 6
  • 16