2

I want to put both 1-dimensional array pointer and 2-dimensional array pointer in a union, so I can access data either way. In the following program I would like to see the value 9 is printed out by both ways.

#include <iostream>
class A {
public:
    union {
        int** array2D;
        int*  array1D;
    };
    A() {
        array2D = new int*[1];
        array2D[0] = new int[1];
    }
};

int main() {
    A a;
    a.array2D[0][0] = 9;
    cout << a.array2D[0][0] << endl;
    cout << a.array1D[0]    << endl;
    cout << a.array2D << endl;
    cout << a.array1D << endl;
}

The actual output:

9
146989080
0x8c2e008 //Pointer address of array2D
0x8c2e008 //Pointer address of array1D

The addresses are identical and by definition multidimensional arrays are stored in the same way as are one-dimensional arrays. I wonder why the two couts print out different results? What did I miss?

EDIT: Thanks to the answers below, I can see what I missed. The fix for accessing data from array1D is:

cout << *( (int*) a.array1D[0]) << endl;

2
  • 2
    Your array1D is 'holding' the pointer to the first row of array2D, in case you weren't aware of that. Commented Apr 23, 2013 at 6:13
  • @WhozCraig Yep I wasn't aware of that :D I thought locating array using new was the same to declaring a fixed-size array, that's what misled me. Commented Apr 23, 2013 at 6:28

3 Answers 3

5

First of all you are invoking undefined-behavior.

the standard says that you are only allowed to read from the member of a union that you last wrote t, reading array2D and array1D interchangeably is therefore not allowed (even though it often works in practice it is not recommended).

Second; using array1D you are trying to dereference and read the value at the address currently (supposedly because of UB) having been allocated for a new int*[1], the value of array2D[0][0] is located one further step down the path.


To access the value you are expecting from a.array1D you will need something as the below (not recommended)

**reinterpret_cast<int**> (a.array1D);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that reinterpret_cast is new to me. I used *( (int*) a.array1D[0] and it works fine, I hope it's safe to use even though I don't know why it is not recommended.
2

When you allocate multidimensional array using new, the way you do it, you are actually allocating a number of arrays. The first one is an array of pointers to array. Thus your a.array1D[0] contains actually pointer to pointer to array, and you are printing a value of the pointer.

I am pretty sure if you will do the following:

cout << (int*)a.array1D[0] << endl;

you will get the same as:

cout << a.array2D[0] << endl;

2 Comments

When you allocate a multidimensional array with new you are allocating one contiguous block: int (*ar)[10] = new int[10][10];. It is not intrinsically an array of pointers. The OP's code is an array of pointers, but it is not a multidimensional array in any way except syntax of usage.
+1 Thats actually one of the better descriptions of how a pointer array is laid out when using one to mimic a multi-dimensional array (and not too wordy either, bravo), and well-worded on how that relates to the OP's question.
2

When you print out the value of a.array2D is points to the beginning of the array. Since you are using a union both array1D and array2D occupy the same space and will contain the same value.

When you access the pointer value in a.array1D[0] you are telling it to get the first element of array1D. Because you are using a union this also points to the first element of array2D which happens to be a pointer.

Comments

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.