简体   繁体   中英

Print the address that stores the pointer points to an array in C

This question may seems quite duplicated; however, I indeed have had a serious survey on this site and still cannot quite understand.

    char str[] = "test";
    printf("%p\n", str);
    printf("%p\n", &str);

I know str itself is a pointer which points to the starting location that stores "t". Therefore I expect that printf("%p\n", str); shows this address (say 000000FFE94FFC34 ). Next, I wish to know in my OS, at what memory location that stores the exact information 000000FFE94FFC34 . (ie the address of str itself.)

However, the output of the third line is the same as the previous one. It seems quite a weird behavior. And how can I figure out the address of str itself? I guess this can be achieved by using another new pointer that points to the pointer I want, ie char **super_pointer = str; but I think it is an unnecessarily complicated way.

Lets draw it out with the pointers added, to hopefully make it simpler to understand:

+--------+--------+--------+--------+--------+
| str[0] | str[1] | str[2] | str[3] | str[4] |
+--------+--------+--------+--------+--------+
^
|
&str[0]
|
&str

As you can see the pointer to the first element ( &str[0] which is what plain str decays to) points to the same location as the array itself ( &str ).

But (and it's an important but): The type are very different!

The type of &str[0] is char * .

The type of &str is char (*)[5] .


On another note you say that

... str itself is a pointer...

This is wrong . str itself is the array, which can decay to a pointer to its first element.

I know str itself is a pointer which points to the starting location that stores "t".

As you wrote "str itself" is not a pointer it is an array. But used in expressions array designators with rare exceptions are converted to pointers to their first elements.

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

In this call

printf("%p\n", str);

the array designator str used as an argument expression is converted to a pointer to its first element. In fact this call is equivalent to

printf("%p\n", &str[0]);

That is this call outputs the starting address of the extent of memory occupied by the array.

This call

printf("%p\n", &str);

that is better to write as and the previous call like

printf("%p\n", ( void * )&str);

also outputs the starting address of the extent of the memory occupied by the array.

What is the difference?

The expression str used in the call of printf has the type char * while the expression &str has the type char ( * )[5] .

The both expressions is interpreted by the call as expressions of the type void * .

To make this more clear consider a two dimensional array

char str[2][6] = { "test1", "test2" };

The addresses of the array as whole and of its first "row" and of its first character of the first "row" are coincide.

That is the expression &sgtr that has the type char ( * )[2][6] and the expression &str[0] that has the type char ( * )[6] and the expression &str[0][0] that has the type char * yield the same value: hhe starting address of the extent of memory occupied by the array..

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