-2

In my assignment, I am to find a sum grid using dynamic arrays. Here is my code without the use of dynamic arrays (I used a 2d array). I made the size dependent on user input. Can someone help me understand and implement dynamic arrays in this code? If you need, I can post all of my code to help you understand what I am trying to do.

void sumGrid(int array[], int& Size)
{
    cout << "Sum Grid" << endl;
    int a2d[Size][Size];
    for (int i = 0; i < Size; i++)
    {
        for (int j = 0; j < Size; j++) 
        {
            a2d[i][j] = array[i] + array[j];
        }
    }
    cout << "  " << setw(7);
    for (int j = 0; j < Size; j++)
    {
        cout << setw(7) << array[j] << ' ';
    }
    cout << endl;
    for ( int k = 0; k < Size; k++)
    {
        cout << array[k] << ' ';
        for (int l = 0; l < Size; l++) 
        {
            cout << setw(7) << a2d[k][l] << ' ';
        }
        cout << endl;
    }
    cout << endl;
}

The output of my code looks like:

Sum Grid
        1       2       3 
1       2       3       4 
2       3       4       5 
3       4       5       6 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
svg
  • 1
  • 1
    [std::vector](https://en.cppreference.com/w/cpp/container/vector) is what you should use. But I suspect that by "dynamic array" your teacher means raw `new/delete` ... which I will not comment upon. – bolov Feb 10 '21 at 01:22

1 Answers1

2

The statement int a2d[Size][Size]; is defining a Variable-Length Array, since Size is not a compile-time constant. VLAs are not part of standard C++, so they should be avoided. The correct and standard way to allocate a dynamic array is to use the new[] operator (see 1, 2), eg:

void sumGrid(int array[], int& Size)
{
    cout << "Sum Grid" << endl;

    int **a2d = new int*[Size];

    for (int i = 0; i < Size; i++)
    {
        a2d[i] = new int[Size];

        for (int j = 0; j < Size; j++) 
        {
            a2d[i][j] = array[i] + array[j];
        }
    }
    cout << "  " << setw(7);
    for (int j = 0; j < Size; j++)
    {
        cout << setw(7) << array[j] << ' ';
    }
    cout << endl;
    for ( int k = 0; k < Size; k++)
    {
        cout << array[k] << ' ';
        for (int l = 0; l < Size; l++) 
        {
            cout << setw(7) << a2d[k][l] << ' ';
        }
        cout << endl;
    }
    cout << endl;

    for (int i = 0; i < Size; i++)
    {
        delete[] a2d[i];
    }
    delete[] a2d;
}

Alternatively, using a 1d array that mimics a 2d array, so that the entire array is allocated sequentially in memory and not scattered around memory:

void sumGrid(int array[], int& Size)
{
    cout << "Sum Grid" << endl;

    int *a2d = new int[Size*Size];

    for (int i = 0; i < Size; i++)
    {
        for (int j = 0; j < Size; j++) 
        {
            a2d[(i*Size)+j] = array[i] + array[j];
        }
    }
    cout << "  " << setw(7);
    for (int j = 0; j < Size; j++)
    {
        cout << setw(7) << array[j] << ' ';
    }
    cout << endl;
    for ( int k = 0; k < Size; k++)
    {
        cout << array[k] << ' ';
        for (int l = 0; l < Size; l++) 
        {
            cout << setw(7) << a2d[(k*Size)+l] << ' ';
        }
        cout << endl;
    }
    cout << endl;

    delete[] a2d;
}

That being said, you should avoid using new[]/delete[] directly, as it is error-prone, and particularly risks leaking memory if an error occurs. Use the standard std::vector container instead, let it handle the memory management for you, eg:

Using a 2d sparse array:

#include <vector>

void sumGrid(int array[], int& Size)
{
    cout << "Sum Grid" << endl;

    std::vector<std::vector<int>> a2d(Size);

    for (int i = 0; i < Size; i++)
    {
        a2d[i].resize(Size);

        for (int j = 0; j < Size; j++) 
        {
            a2d[i][j] = array[i] + array[j];
        }
    }
    cout << "  " << setw(7);
    for (int j = 0; j < Size; j++)
    {
        cout << setw(7) << array[j] << ' ';
    }
    cout << endl;
    for ( int k = 0; k < Size; k++)
    {
        cout << array[k] << ' ';
        for (int l = 0; l < Size; l++) 
        {
            cout << setw(7) << a2d[k][l] << ' ';
        }
        cout << endl;
    }
    cout << endl;
}

Using a 1d sequential array:

#include <vector>

void sumGrid(int array[], int& Size)
{
    cout << "Sum Grid" << endl;

    std::vector<int> a2d(Size * Size);

    for (int i = 0; i < Size; i++)
    {
        for (int j = 0; j < Size; j++) 
        {
            a2d[(i*Size)+j] = array[i] + array[j];
        }
    }
    cout << "  " << setw(7);
    for (int j = 0; j < Size; j++)
    {
        cout << setw(7) << array[j] << ' ';
    }
    cout << endl;
    for ( int k = 0; k < Size; k++)
    {
        cout << array[k] << ' ';
        for (int l = 0; l < Size; l++) 
        {
            cout << setw(7) << a2d[(k*Size)+l] << ' ';
        }
        cout << endl;
    }
    cout << endl;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you so much for everything!. It really works the way I wanted it to. Can you explain what is going on here though? Really want to understand it. – svg Feb 10 '21 at 01:39
  • int **a2d = new int*[Size]; for (int i = 0; i < Size; i++) { a2d[i] = new int[Size]; – svg Feb 10 '21 at 01:39
  • @svg190 that is allocating `a2d` as a 1d array of `Size` number of `int*` pointers, where each `int*` is pointing at a 1d array of `Size` number of `int`s. Whereas the original code (`int a2d[Size][Size];`) is allocating `a2d` as a single contiguous array of `Size*Size` number of `int`s - similar to my alternative examples. – Remy Lebeau Feb 10 '21 at 01:44
  • Thanks again. I understand now. It is an array pointing to arrays! – svg Feb 10 '21 at 01:47