0

I've been working on a class project program using pointers and arrays with pointer offset notation (I think). Below is the diagram used for the project

Prompt for project

*The shaded boxes represent pointers. The unshaded boxes represent a dynamically allocated two dimensional int array. Your program cannot create named identifiers for any of the unnamed items. The number of rows and the number of columns will be user input. The ellipses in the diagram represent that the sizes of the rows and columns are variable. The vertical array is an array of pointers. Each of the vertical array elements points to a one dimensional array of integers.

Diagram

In your program only refer to the integer array through the pointers represented by s, t, u, and v. When passing to functions you must always pass these pointers. You cannot dereference actual parameters in a function call. Nor can you dereference pointers and assign them to variables just in order to work with them.*

#include <iostream>
using namespace std;


void fillArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        *(pArray + row) = new int;
        cout << "Enter " <<  " row " << row + 1<< endl;

        for(int col = 0; col < columns; col++)
        {
            cin >> *(*(pArray + row) + col);
        }
    }
}

void printArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        cout << "Row " << row + 1 << endl;
        for(int col = 0; col < columns; col++)
        {
            int num = *(*(pArray + row) + col);
            cout << num << " ";
        }
        cout << endl;

    }
}

void reverseArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        cout << "Reversed Row " << row + 1 << endl;
        for(int col = columns - 1; col >= 0; col--)
        {
            int num = *(*(pArray + row) + col);
            cout << num << " ";
        }
        cout << endl;
    }
}


int main()
{
    int rows;
    int columns;
    cout << ("Input number of rows: ");
    cin >> rows;
    cout << ("Input number of columns: ");
    cin >> columns;

    int **pArray;                   //Initialize array

    int ****s;                      //Initialize pointers s, t, u, v
    **s = pArray;
    int ****t;
    *t = *s;
    int ****u;
    **u = pArray;
    int ****v;
    *v = *u;


    pArray = new int*[rows];        //create pointer to rows. 1st level of indirection
    *pArray = new int[columns];     //create pointer to columns. 2nd level of indirection

    fillArray(pArray, rows, columns);
    printArray(pArray, rows, columns);
    reverseArray(pArray, rows, columns);

    //Loop to terminate program
    while (true)
    {
        cout << "\nEnter letter \'q\' to terminate program\n";
        char c;
        cin >> c;

        if(c == 'q')
            break;
    }
}

Sorry for the poor code formatting. I couldn't understand how to copy and paste in code block.

So my question is, how do I implement the diagram with my program. I started with the basics of creating the array using pointer offset and labeling it with it's own name.

I believe I have to change all of my references to work with the pointer variables 's, t, u, v.' Any help is appreciated.

9
  • What shaded boxes, unshaded boxes, and ellipses? Commented Jan 30, 2013 at 1:42
  • 8
    I feel sorry for you that your teacher thinks writing code like this is educating... Commented Jan 30, 2013 at 1:42
  • You can just paste your code, select it, and press the button with the {} icon (or press Ctrl+K) and it will be formatted properly. Maybe it won't work properly if you use tabs instead of spaces, though. Commented Jan 30, 2013 at 1:46
  • Thanks for the replies guys. Let me fix my formatting and then I'll get back to you! @Chris the shaded boxes and what not are in the link Commented Jan 30, 2013 at 1:51
  • 2
    int ****s: if there is no way around excessive pointing, I would very strongly recommend that you typedef the levels of array, so that we don't lose you to Codethulhu. Commented Jan 30, 2013 at 2:05

1 Answer 1

1

In an effort to be at least somewhat helpful, note that the question is not crystal-clear on whether the arrays are fixed or variant You're given two sizes; a column count (the width) and a row count (the height). Also note that this statement:

"In your program only refer to the integer array..."

is nonsense. there are 'cols' integer arrays, not one.

int rows, cols; // acquire rows and cols from wherever.

// create the row vector that will hold the column pointers.
//  this constitutes the first grey box above the main array.

int **rowsp = new int*[rows];


// for each slot we just allocated, set the value an allocation
//  of 'int' values. the list will be `cols` wide

for (int i=0;i<rows;)
    rowsp[i++] = new int[cols];


// thats both white boxes and the first grey box. rowsp points
//  to the allocated pointer array holding 'rows' pointers, each 
//  pointing to an int array hold 'cols' ints.

// now we make the two pointers that point at rowsp
int ***p1 = &rowsp;
int ***p2 = p1;

// and finally, setup s,t,u,v
int ****s = &p1;
int ****t = s;
int ****u = &p2;
int ****v = u;

Terrific, but reading the context of your question, this isn't right at all. According to the question, you have only four pointers to work with: {s,t,u,v} The must be declared of a type appropriate to allow us to build all the way to the end int arrays. Looking at the above (which is throw-way code at this point) we know we need four levels of indirection. So this time, we start with s,t,u, and v, working our way down.

int ****s = new int***; // p1 in the prior code
int ****t = s;          // points to the same p1

int ****u = new int***; // p2 in the prior code
int ****v = u;          // points to the same p2

Now we need to get our p1 and p2 pointing to a common pointer as well. This pointer will be the rowsp pointer in out code from above (which means when we're done s,t,u, and v all should have a path to it eventually)

*s = new int**;         // s-->p1-->rowsp, t-->p1-->rows
*u = *s;                // u-->p2-->rowsp, v-->p2-->rowsp

Now we need to allocate the actual rows vector, which will contain pointers to ints:

**s = new int*[rows];   // the integer pointer array.

And finally, populate this array with 'cols'-length int-arrays.

for (int i=0;i<cols;++i)
{
    *(**s+i) = new int[ cols ]();
    for (int j=0;j<cols;++j)
        *(*(**s+i)+j) = i+j; // <== beautiful dereference chain =P
}

If we did this right, the following should all point to the same thing:

cout << "**s = " << **s << endl;
cout << "**t = " << **t << endl;
cout << "**u = " << **u << endl;
cout << "**v = " << **v << endl;

I leave moving this madness to functions on your own dime. The entire code base from above appears below in one contiguous listing. You can also see it live on ideone.com:

#include <iostream>

using namespace std;

int main()
{
    static const int rows = 8; // yours would come from user input
    static const int cols = 9;

    int ****s = new int***; // s --> p1
    int ****t = s;          // t --> p1

    int ****u = new int***; // u --> p2
    int ****v = u;          // v --> p2

    *s = new int**;         // s-->p1-->rowsp, t-->p1-->rows
    *u = *s;                // u-->p2-->rowsp, v-->p2-->rowsp

    **s = new int*[rows];   // s --> p1 --> rowsp --> int*[rows]

    for (int i=0;i<rows;++i)
    {
        *(**s+i) = new int[ cols ];
        for (int j=0;j<cols;++j)
            *(*(**s+i)+j) = (i+j) % cols; // <== beautiful dereference chain =P
    }

    cout << "**s = " << **s << endl;
    cout << "**t = " << **t << endl;
    cout << "**u = " << **u << endl;
    cout << "**v = " << **v << endl << endl;;

    cout << "======= S =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**s+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= T =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**t+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= U =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**u+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= V =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**v+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    // delete rows.
    for (int i=0;i<rows;++i)
        delete [] *(**s+i);

    // delete row pointer array
    delete [] **s;

    // delete rowsp pointer
    delete *s;

    // and finally, delete s and u (or t and v)
    delete s;
    delete u;

    return 0;
}

Output (pointers will vary)

**s = 0x100103b60
**t = 0x100103b60
**u = 0x100103b60
**v = 0x100103b60

======= S =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= T =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= U =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= V =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 
Sign up to request clarification or add additional context in comments.

2 Comments

I did, more or less the same thing, and was about to post as your post streamed in... Good job and clean (well, as clean as can be given the ugly problem/assignment) code.
@NikBougalis yeah, but I have to admit, the indirection math made me think a few times (two to be precise), just because I'd never find myself in a place needed that deep a pointer-set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.