brainydexter
brainydexter

Reputation: 20346

can i represent multi dimension array using pointers?

Given the following code, I'm trying to understand if the pointer manipulation is legit:

struct Foo{
 int *temp1;
}

temp1 => 2d array

struct Foo1{
 int temp1[2][2];
}

temp1 => 3d array

struct Foo2{
 int temp1[3][2][3];
}

I assign value to Foo1 and Foo2 using static data. For e.g.:

Foo1 f1 =
{
 { 2, 4 },
 { 1, 3 }
};

Foo2 f2 = 
{
   {
       {
           {101, 102, 103},
           {104, 105, 106},
       },
       {
           {107, 108, 109},
           {110, 111, 112},
       },
       {
           {113, 114, 115},
           {116, 117, 118},
       },
   }
};

Can I reference Foo data from Foo1 like this:

Foo f;
f.temp1 = (int*)f1.temp1;
for(int i = 0; i < 2; ++i)
{
 for(int j = 0; j < 2; ++j)
 {
  cout << "i " << i << " j " << j << " value: " << f.temp1[(i * 2) + j] << endl;
 }
}

Can I reference Foo data from Foo2 like this:

Foo f;
f.temp1 = (int*)f2.temp1;
for(int i = 0; i < 3; ++i)
{
 for(int j = 0; j < 2; ++j)
 {
   for(int k = 0; k < 3; ++k)
   {
    cout << "i " << i << " j " << j << " k " << k << " value: " << f.temp1[(i * 3 * 2) + (j * 2) + k] << endl;
   }
 }
}

Essentially, I am assuming the array is going to arranged in contiguous memory and can I dereference it like this ?

Upvotes: 0

Views: 96

Answers (2)

david.pfx
david.pfx

Reputation: 10868

The standard says clearly and explicitly that the answer is yes. See n3797 s8.3.4. Some of the language is hard to read, but the final note says:

[Note: It follows from all this that arrays in C++ are stored row-wise (last subscript varies fastest) and that the first subscript in the declaration helps determine the amount of storage consumed by an array but plays no other part in subscript calculations. —end note ]

So you can reference the storage in any array by a calculation that uses simple pointer arithmetic, and iterate over all the storage in any array simply by incrementing a pointer.

Please note that arrays are not required to be packed. They usually are, but there could be padding inserted between elements (but not extra padding between rows or columns).

Upvotes: 1

merlin2011
merlin2011

Reputation: 75545

The answer to this question suggests that the answer is yes. Multidimensional arrays are indeed laid out contiguously in memory, assuming they are declared with the [size1][size2][size3] notation.

Empirically, the answer is also yes. Consider the following code, which I wrote by cobbling together the fragments you wrote in your question.

#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;
struct Foo {
    int *temp1;
};

struct Foo1{
    int temp1[2][2];
};

struct Foo2{
    int temp1[3][2][3];
};


Foo1 f1 =
{
    {
        { 2, 4 },
        { 1, 3 }
    }
};
Foo2 f2 = 
{
    {
        {
            {101, 102, 103},
            {104, 105, 106},
        },
        {
            {107, 108, 109},
            {110, 111, 112},
        },
        {
            {113, 114, 115},
            {116, 117, 118},
        },
    }
};


int main(){


    int* temp1 = (int*) f1.temp1;
    for(int i = 0; i < 2; ++i)
        for(int j = 0; j < 2; ++j)
            cout << "i " << i << " j " << j << " value: " 
                << temp1[(i * 2) + j] << endl;

    temp1 = (int*) f2.temp1;
    cout << endl;
    for(int i = 0; i < 3; ++i)
        for(int j = 0; j < 2; ++j)
            for(int k = 0; k < 3; ++k)
                cout << "i " << i << " j " << j << " k " << k << " value: " 
                    << temp1[(i * 3 * 2) + (j * 3) + k] << endl;
}

Output:

i 0 j 0 value: 2
i 0 j 1 value: 4
i 1 j 0 value: 1
i 1 j 1 value: 3

i 0 j 0 k 0 value: 101
i 0 j 0 k 1 value: 102
i 0 j 0 k 2 value: 103
i 0 j 1 k 0 value: 104
i 0 j 1 k 1 value: 105
i 0 j 1 k 2 value: 106
i 1 j 0 k 0 value: 107
i 1 j 0 k 1 value: 108
i 1 j 0 k 2 value: 109
i 1 j 1 k 0 value: 110
i 1 j 1 k 1 value: 111
i 1 j 1 k 2 value: 112
i 2 j 0 k 0 value: 113
i 2 j 0 k 1 value: 114
i 2 j 0 k 2 value: 115
i 2 j 1 k 0 value: 116
i 2 j 1 k 1 value: 117
i 2 j 1 k 2 value: 118

Upvotes: 1

Related Questions