Home > Blockchain >  accessing elements in 2D pointer pointing to an dynamic array C
accessing elements in 2D pointer pointing to an dynamic array C

Time:12-23

#include <iostream>

using namespace std;

void create(int **map);

int main(){
    int **map;
    create(map);
    cout << endl << "printing map in main" << endl;
  for (int i = 0; i < x; i  ) {
    for (int j = 0; j < y; j  ) {
        map[i][j] = 1;
        cout << map[i][j] << " ";
    }
    cout << endl;
}
    return 0;
}

void create(int **map) {
    int x = 8, y = 8;

    map = new int* [x];

    for (int i = 0; i < x; i  ) {
        map[i] = new int[y];
    }

    for (int i = 0; i < x; i  ) {
        for (int j = 0; j < y; j  ) {
            map[i][j] = 1;
            cout << map[i][j] << " ";
        }
        cout << endl;    
    }
 }

I've been trying to read in the elements from 2D pointer that is pointing to a dynamic array in main function but i can't seem to get it work, i've tried reading it using double for loops and ((map i) j) but to no avail

CodePudding user response:

You need to declare the parameter as having a referenced type. For example

void create(int ** &map);

In this case the pointer map declared in main will be changed within the function.

Otherwise the function deals with its local variable (parameter) map and the pointer map declared in main will be unchanged..

Also it is a bad idea to use magic numbers like 8. The function will be more flexible and general if the sizes of an array can be passed to the function. For exampele

void create( int ** &map, size_t m, size_t n ) 
{
    map = new int * [m];

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

    for ( size_t i = 0; i < m; i   ) 
    {
        for ( size_t j = 0; j < n; j   ) 
        {
            map[i][j] = 1;
            cout << map[i][j] << " ";
        }
        cout << endl;    
    }
}

And in main you could write

size_t m = 8, n = 8;

int **map  = nullptr;

create( map, m, n );

cout << endl << "printing map in main" << endl;

for ( size_t i = 0; i < m; i   ) 
{
    for ( size_t j = 0; j < n; j   ) 
    {
        cout << map[i][j] << " ";
    }
    cout << endl;
}

CodePudding user response:

Instead of passing a pointer to create() you should return it. Like this:

int main(){
    int **map = create();
    cout << endl << "printing map in main" << endl;
    return 0;
}

int ** create() {
    int x = 8, y = 8;

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

    for (int i = 0; i < x; i  ) {
        map[i] = new int[y];
    }

    for (int i = 0; i < x; i  ) {
        for (int j = 0; j < y; j  ) {
            map[i][j] = 1;
            cout << map[i][j] << " ";
        }
        cout << endl; 
    }
   
    return map;
 }

Also you should add a delete for the allocated matrix.

CodePudding user response:

Your code with a bit of refactoring:

#include <iostream>


int** create2DArray( const std::size_t rowCount, const std::size_t colCount );
void delete2DArray( int** const array2D, const std::size_t rowCount );
void print2DArray( int** const array2D, const std::size_t rowCount, const std::size_t colCount );

int main( )
{
    constexpr std::size_t ROW_COUNT { 8 };
    constexpr std::size_t COL_COUNT { 8 };

    int** map { create2DArray( ROW_COUNT, COL_COUNT ) };

    std::cout << '\n' << "printing map in main" << '\n';
    print2DArray( map, ROW_COUNT, COL_COUNT );

    // after work is done with array, delete it
    delete2DArray( map, ROW_COUNT );
    map = nullptr; // to prevent it from becoming a dangling pointer

    return 0;
}

int** create2DArray( const std::size_t rowCount, const std::size_t colCount )
{
    int** const array2D = new int* [rowCount];

    for ( std::size_t row = 0; row < rowCount;   row )
    {
        array2D[row] = new int[colCount];
    }

    for ( std::size_t row = 0; row < rowCount;   row )
    {
        for ( std::size_t col = 0; col < colCount;   col )
        {
            array2D[row][col] = 1;
        }
    }

    return array2D;
}

void delete2DArray( int** const array2D, const std::size_t rowCount )
{
    for ( std::size_t row = 0; row < rowCount;   row )
    {
        delete[] array2D[row];
    }

    delete[] array2D;
}

void print2DArray( int** const array2D, const std::size_t rowCount, const std::size_t colCount )
{
    for ( std::size_t row = 0; row < rowCount;   row )
    {
        for ( std::size_t col = 0; col < colCount;   col )
        {
            std::cout << array2D[row][col] << " ";
        }

        std::cout << '\n';
    }
}

The output:


printing map in main
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

Note #1: When constexpr is used in the declaration of a variable, that variable is evaluated at compile-time and not run-time and becomes a constant expression. So it's good practice to declare variable with constant value (e.g. an immediate like 5 or 3.7) as constexpr.
Check constexpr (C ) for more details.

Note #2: std::size_t is an unsigned integral type. On my compiler it is the equivalent of unsigned long long int (which BTW has a size of 8 bytes).
Here it is from this std::size_t:

typedef /*implementation-defined*/ size_t;
  • Related