Home > front end >  How to get the address of an array pointer?
How to get the address of an array pointer?

Time:02-19

I have the following c code:

int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int **pp = &arr;

The compiler complains and I don't know why. Isn't arr a pointer points to an int array? I should be able to assign the address of it to a int**. Are there any other way to do it?

CodePudding user response:

Isn't arr a pointer points to an int array?

No, arr isn't a pointer at all. arr is an array. If you take the address of arr, what you get is a pointer to an array, not a pointer to a pointer. This would work:

int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int (*pp)[8] = &arr;

// cleaner by using a type alias:
using Arr8 = int[8];
Arr8* pp = &arr;

If you want a pointer to pointer, then you must first create a pointer to which you could point at:

int*  p  = arr; // same as = &arr[0]
int** pp = &p;

But when I do printf("arr: %x\n", arr);. It actually prints out the starting address of arr. Doesn't that mean it is a variable stores the address of the array?

It does not mean that. arr is the array; it doesn't store the address of the array, and the type of the variabe isn't a pointer.

When you pass an array as a variadic argument, it will implicitly convert to a pointer to first element. That is the same implicit conversion that happens in the example above: int* p = arr;.

Note that %x format specifier requires that the argument is of type int (or smimilar). int* (which is the resulting type of the implicit conversion) is the wrong type, and hence the behaviour of the program will be undefined.

CodePudding user response:

If you have an object declared like

T x;

where T is some type specifier then a declarations of a pointer to such an object will look like

T *p = &x;

Now consider the array

int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};

using this type def

typedef int T[8]:

you can rewrite the array declaration like

T arr = {1, 2, 3, 4, 5, 6, 7, 8};

So a pointer declaration to the object arr will look like

T *p = &arr;

As the type specifier T represents the type int[8] then a pointer to an object of this type will have the type int ( * )[8].

So the above declaration looks like

int ( *p )[8] = &arr;

As for the declaration

int **pp;

then it can be introduced the following way

int *p = arr;
int **pp = &p;

That is in the first declaration

int *p = arr;

the array designator arr is implicitly converted to pointer to its first element. So the pointer p is initialized by the address of the first element of the array arr.

In turn the pointer pp is initialized by the address of the pointer p.

CodePudding user response:

Arrays and pointers are fundamentally different things:

  • think of an array as a street with buildings: each building has a number and the street has a name. In the definition int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8}; The array name arr is like the street name and the array elements numbered 0 to 7 are buildings containing each a number.

  • a pointer is an object that contains the address to an object: a piece of paper with the address of a building: char *p = &arr[1]; is akin to writing 1, street arr on a piece of paper. As a convenience, but rather o confusing one, char *p = arr; is equivalent to char *p = &arr[0]; just like telling your GPS to go to fifth street will take you to the first house on that street.

  • a pointer to a pointer, int **pp is a piece of paper where you write the place where to find another piece of paper that has the address of the building in the above paragraph. This type of pointer may be required in some circumstances, but not as common as regular pointers.

  • the definition int **pp = &arr; is incorrect because &arr is not the address of a pointer. It is the address of the full array arr, is a special type of pointer, like a deed is a special type of paper describing an actual property: the full extend of street arr, comprising pavement, sidewalks, lots and constructions erected thereupon. A pointer to a full array has a special syntax: int (*p)[8] = &arr; It is only used in advanced C programming. Most programmers will never need one and might not even understand the syntax, just like in real life, property deeds are seldom seen outside lawyers' offices and official places and mostly abstruse to the populace.

  • For your purpose, you can define a pointer to int and make it point to the beginning of the array: int *p = arr; And if you really need a pointer to a pointer to int, you can define pp as int **pp = &p;

  • accessing the 3rd element of the array via pp will be written (*pp)[3] or pp[0][3]1.


1 among other less readable possibilities: *(*pp 3), *(3 *pp) and downright obscure alternatives: 3[*pp], 3[0[pp]]...

CodePudding user response:

Case 1

Here we consider the statement:

int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};

The above statement creates an array named arr of size 8 with int elements. The type of the array arr is int [8].

Case 2

Here we consider the statement:

int **pp = &arr;

The following are the things to note about the above statement:

  1. On the left hand side, we have a pointer to a pointer to an int named pp. That is, the type of pp on the left hand side is int**.
  2. On the right hand side, we have the expression &arr. Since from case 1, we know that the type of the array arr is int [8]. Therefore, &arr is int (*)[8] which is read as a pointer to an array of size 8 with elements of type int.

So essentially, the type on the left hand side is int**(from point 1) while the type on the right hand side is int (*)[8] (from point 2). That is, the type on the left hand side and the right hand side don't match. And this is why the compiler gives us the error saying:

error: cannot convert ‘int (*)[8]’ to ‘int**’ in initialization

Which means you're trying to initialize pp which is an int** with the initializer of type int (*)[8].

To solve this you need to make sure that the type on the left and right hand side match as shown below:

int arr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int (*pp)[8] = &arr; //now the type on rhs and lhs match

Now the type of pp on the left hand side is int (*)[8] which matches with the type of &arr on the right hand side and hence this program work fine.

CodePudding user response:

array name is itself the address of [0] index so just make a pointer like this int *p=array_name; now just increment the pointer and access the array, like this. *(array_name i) where i could be any index which u want to access.

CodePudding user response:

It maybe the cause that the array "arr[8]" contains a value stored in the executable image (precisely ".data" section). So the pointer contains a fixed value because of optimization. And that variable is virtual (like a macro) and have not a real source. This maybe fixed by performing an operation on the "arr[8]" variable like incrementing it's pointer or making it global or creating a variable that references "arr[8]"

After that try pointing to both "pointer to arr[8]" and "arr[8]" and it may be fixed.

  • Related