0

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 ?

3
  • Do you have a good reason not to use STD containers? Commented May 21, 2014 at 6:14
  • @Biffen: Yes. If I use vectors (and nope, cant do c++1x either), I will have to copy the data into those containers which is a big no-no for this requirement. I have a LOT of data and copying it into these containers will take a lot of time, which is not acceptable in my environment. Commented May 21, 2014 at 18:14
  • Sounds like a good reason. :) Commented May 21, 2014 at 18:17

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

I have a question from the link you referenced. So, we can't really use int** for 2d arrays, but use a single pointer as I mentioned above ?
1

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).

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.