Search code examples
arrayscpointersprintfimplicit-conversion

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. (i.e. 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, i.e. char **super_pointer = str; but I think it is an unnecessarily complicated way.


Solution

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