Hi all,

I am fairly new to C++, but i am having trouble declaring a 2D dynamic array.

Any help will be appreciated.

Thanks

Please show us what you've tried, and explain just what you're trying to accomplish.

I could dust off my lecture, or you could do a little searching. Googling "c++ 2D dynamic array" brings up several hits that look helpful.

the psudeocode will be

datatype name [no of rows][no of cols];

e.g. int array[10][10];

This is a post on blackboard from a class-mate of mine--

/**
 * Posted by 'Gregg'
 */

 ptr_practice1.cpp  (3.139 Kb)

When you create a 2 dimensional array on the stack, both the row and column values must be known at compile time, which is why you must use either literals or const variables as array size parameters.  So if you want to make both the rows and columns of an array be allocated dynamically in the heap memory at runtime, there's a couple of ways to go about it. The first is to create a new dynamic1D array like we did in class with scores array, just make the number of elements needed rows * columns:

int maxRows, maxColumns;

Use cin to get the max rows and columns from the user.

int* scores = new int[maxRows * maxColumns];

To access the elements, you can use either array or pointer notation. So to access row 2, column 3 (remember, arrays are 0 based):

whatsAtRow2Col3 = scores[((row -1) * maxColumns) + (column - 1)];

or

whatsAtRow2Col3 =*(scores + ((row - 1) * maxColumns) + (column - 1));

Another way to make multi dimensional arrays is using a concept known as pointer to pointers. Like Ron was saying on thursday, most of think of a 2D array like a spreadsheet with rows and columns (which is just fine), but 'under the hood', C++ is using ptr to ptrs. First, you start off with creating a base pointer. Next, allocate an array of row pointers and assign the address of the first one to the base pointer. Next, allocate memory to hold each rows column data and assign the address in the row pointer array:

int maxRows = 5, maxColumns = 15;

int** basePtr;

basePtr = new int*[maxRows];

for (int row = 0; row < maxRows; row++)
{
       basePtr[row] = new int[maxColumns];

}

To visualize this:

                   ROW POINTER ARRAY             COL DATA ARRAYS

basePtr -->  row 0 points to columns 0 array --> XXXXXXXXXXXXXXX

             row 4 points to columns 4 array --> XXXXXXXXXXXXXXX

As with the first example, you can access this 2D array with either array or pointer notation, so if you want the value at row 2, column 3, (remember, arrays are 0 based) either:

whatsAtRow2Col3 = basePtr[row - 1][column - 1] ;

or

whatsAtRow2Col3 = *(*(basePtr + row - 1) + column - 1);

I know this sounds a little confusing, but the more you work with this stuff, the clearer things become. I've attached one of my practice cpp files that I wrote to figure out the above explainations called ptr_practice.cpp.

Cheers,

Gregg

             row 1 points to columns 1 array --> XXXXXXXXXXXXXXX

             row 2 points to columns 2 array --> XXXXXXXXXXXXXXX
             row 3 points to columns 3 array --> XXXXXXXXXXXXXXX

I believe some of the information got cut off due to blackboards formatting, but the idea is straightforward enough.

Also, here's an example of a random-jagged 2D array using vectors--

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <ctime>

using std::cout;
using std::cin;
using std::flush;
using std::endl;
using std::vector;
using std::size_t;
using std::stringstream;
using std::string;

int main(){

    {
        vector< vector<int> > twoDimArray (0); // a vector that can hold vector<int>'s
        size_t amount = 0; // an unsigned int initialized to be 0
        string input = ""; // a string initialized to be empty
        bool failed = true; // a condition initialized to be true

        do{
            stringstream ss (stringstream::in | stringstream::out); // a buffer that can pull in string information and can
                                                                    // have its string information extracted
            cout << "Please enter a the amount of vectors you would like to create. " << flush; // display information to console
            cin >> input; // obtain input from user
            ss << input; // toss the chars inside input into the stringstream
            if( (ss >> amount) )
                failed = false; // if the operation is successful, we obviously did not fail
            input.clear(); // empty the string
        }while(failed); // continue until the user complies with valid information

        srand( (clock()) ); // seed the random number generator, based on the current time

        for(size_t i = 0; i < amount; i++) // perform instructions below the same number of times as the number given by userr
            twoDimArray.push_back( vector<int>( rand() % 20  , 0 )); // generate a vector with a random size of 0-19
                                                                     // and push into the vector that holds vector<int>'s
        size_t e = 1; // assuming at least 1 vector

        /*
            The set of instructions below perform the following:
            -Initialize an iterator for vectors of vector<int>'s named i to be that of twoDimArray.begin()
             which means i's position is that of the first value of twoDimArray
            -If i doesn't point to the same reference as the last reference pointed to by twoDimArray.end()
                Increment e and also shift i to point to the next value
                Print out the size of the vector<int> held by twoDimArray
         */
        for(vector< vector<int> >::iterator i = twoDimArray.begin(); i != twoDimArray.end(); e++, i++)
            cout << "vector " << e << " has size: " << (*i).size() << endl;

    } // end scope

    cin.ignore(); // ignore 1 character of input held by the input-buffer
    cin.get(); // pause the program in a platform independant manner
    return 0;
} // end main

I do not want to use vectors. Also I have declared my array in the following format:

int size = 2;
int array[size][size]

but in the above case i have to specific as to what my size is going to be.

I want to fin>>size from a file and then use it to declare the size of the array.

Thanks For helping

Read the article posted above, starting at

Another way to make multi dimensional arrays is using a concept known as pointer to pointers. Like Ron was saying on thursday, most of think of a 2D array like a spreadsheet with rows and columns (which is just fine), but...

That tells you how to allocate dynamic 2D array based on user or file input.

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

to make it simple

for dynamic 2darray just use the following code...........

#include <iostream.h>

void main() {
    const int rows = 4;
    const int cols = 4;

    // declaration
    int ** a;

    // allocation
    a = new int*[rows];
    for(int i = 0; i < rows; i++)
        a[i] = new int[cols];

    // initialization
    for(int j = 0; j < rows; j++)
        for(int i = 0; i < rows; i++)
            a[i][j] = 0;
}

wrkng absuletly f9...

Edited 3 Years Ago by Dani: Formatting fixed

try this one:

// DMA of 2D array in C++
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int x = 3, y = 3;

    int **ptr = new int *[x];

    for(int i = 0; i<y; i++)
    {
        ptr[i] = new int[y];
    }
    srand(time(0));

    for(int j = 0; j<x; j++)
    {
        for(int k = 0; k<y; k++)
        {
            int a = rand()%10;
            ptr[j][k] = a;
            cout<<ptr[j][k]<<" ";
        }
        cout<<endl;
    }
}

i have 1 question: for use dynamic arrays, can i use normal variables instead pointers?

Pointers are normal variables. But when it comes to "dynamic" arrays, it's a bit of a misnomer because you're not creating an array, you're simulating one with dynamic memory allocation.

Really the best you can get is to hide the pointers in a class implementation. Both std::string or std::vector are "dynamic" arrays under the hood, but it's hidden by the class interface.

This article has been dead for over six months. Start a new discussion instead.