简体   繁体   中英

Correct way to initialize pointer to array in C++ ?

Consider the code :

const int MAX = 3;
int (*array)[MAX]  ;

int intArray[3] = {30 , 40 , 50};

array = &intArray;
for (int h = 0 ; h < MAX ; h++)
{
    std::cout << *(array[h]) << std::endl;
}

The output is :

30
0
3

Clearly something is wrong with the initialization of the array , why do I get 30 , 0 , 3 and not 30,40,50 ?

Just like that:

const int MAX = 3;
int *array;

int intArray[3] = {30 , 40 , 50};

array = intArray;
for (int h = 0 ; h < MAX ; h++)
{
    std::cout << array[h] << std::endl;
}

The handling of built-in arrays in C++ is quite peculiar, especially when considering pointers. A pointer can be seen as one of two things:

  • as pointer to a single object
  • as pointer to the first element of an array

So how does this work? Well, let's start with the definition of your array, and let's define a pointer to the array in the way it is normally done in C++:

const int MAX = 3;
int *array;                           // (1)

int intArray[3] = {30 , 40 , 50};

array = intArray;                     // (2)
for (int h = 0 ; h < MAX ; h++)
{
  std::cout << array[h] << std::endl; // (3)
}

Now what is happening here?

At line (1) we define a pointer to int named array . Note: Not specifically a pointer to array of int , but a pointer to plain int .

At line (2) we assign intArray to that pointer. Now intArray is an array, so how can we assign it to a pointer? Well, here comes the magic: If an array is used in an rvalue context (that is, in a context where a value is required), then the compiler actually provides a pointer to the first element. That is, the line is completely equivalent to

array = &(intArray[0]);

Now in line (3) we access array[h] . That is, we access the pointer as if it were an array. So what happens here? Well, the pointer is interpreted as pointing to the first element of an array, and the element h of that array is accessed. What actually happens is that the compiler replaces array[h] by *(array + h) . That is, it dereferences a pointer that is h int s later than array .

OK, so what does your definition

int (*array)[MAX];

do? Well, just as the previous declaration defined a pointer to int , this defines a pointer to an array of MAX int s, that is, a pointer to int[MAX] . As before, this can point either to a single array of three int s, or to an array of such arrays.

Now when you did

array = &intArray;

you set it to point to the single array intArray .

Now in your output line you wrote:

*(array[h])

So what happens here? Well, in the parentheses you have array[h] , that is, you've used the array subscript operator [] on the pointer array . Therefore the compiler will access the h -th array of three ints in your array of arrays of three ints. Now you only have one array of ints there, so as soon as h > 0 you'll be out of bound. There's absolutely no way to predict the numbers you'll get there (your program could also just have crashed).

However we're not yet finished: Your full expression reads *(array[h]) , so you actually dereference the result of array[h] . But the result of array[h] is an array of 3 int s! Well, the dereference operator expects a pointer value , therefore again the array "decays" to a pointer to its first element, and that of course can be dereferenced, giving the first element of the array. Indeed, you could have equivalently written *(array[h]) as array[h][0] .

And this is also the use case of variables of this type: It would normally be used an variables of the form

int intArray[3][3] = {{30, 40, 50}, {300, 400, 500}, {3000, 4000, 5000}};

where you would initialize the pointer with array = intArray and then your loop would output

30
300
3000

OK, but how would you access the values of your intArray with only three values? Well, for that you have to first dereference the pointer in order to get to the array, and then access the array index operator:

std::cout << (*array)[h] << std::endl;

Alternatively you can see it as the first (and only) row of a 1×3 array, and equivalently write

std::cout << array[0][h] << std::endl;
int (*array)[MAX]  ;

This line declare array as pointer to array of MAX integers. so if you want to print intArray using array , you can do something like this

for (int h = 0; h < MAX; h++)
    {
        std::cout << (*array)[h] << std::endl;
    }

You should use (*array)[h] . array is a pointer to the intArray , you should dereference it first.

Since someone thinks that array is of array type which is completely wrong. you can verify with the program

#include <type_traits>
#include <iostream>
using namespace std;
int main() {
  cout << is_array<int*[3]>::value << endl;
  cout << is_array<int(*)[3]>::value << endl;
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM