Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing address a pointer points to, value the address points to, and the address of the pointer itself

Tags:

c

pointers

I wrote a little program to familiarize myself with pointers and relations between them a little more. In order to do this I wrote a small piece of code that just declares and initializes an integer a, then declares a pointer *p to the address of a and then goes on deeper to assign a pointer to a pointer *pp and so on so far up to ****pppp. If I understood pointers correctly a pointer to a pointer to a ... basically works like this:

Address of pointer (or integer) itself: 0x7fff08d1c658    0x7fff08d1c660    0x7fff08d1c668    0x7fff08d1c670    0x7fff08d1c67c
                                              ↑                 ↑                  ↑                ↑                 ↑ 
                                             pppp     -->      ppp       -->      pp      -->       p       -->       a = 42
                                              ↓                 ↓                  ↓                ↓                 
Address pointer points to:              0x7fff08d1c660    0x7fff08d1c668    0x7fff08d1c670    0x7fff08d1c67c

The addresses on the diagonal have to be identical because the previous pointer always points to the address of the next pointer which it has been assigned. Now I want to check this in a program using printf() calls and here I am unsure if the way I print the address the more elaborate pointers **pp, ***ppp, and ****pppp point to and how I print the addresses of these pointers themselves are correct. Could someone point out possible mistakes? Here is the code followed by its output:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a;
    int *p;
    int **pp;
    int ***ppp;
    int ****pppp;

    a = 42;

    /* Take the address of a */
    p = &a;

    /* Take the address of p */
    pp = &p;

    /* Take the address of pp */
    ppp = &pp;


    /* Take the address of ppp */
    pppp = &ppp;

    printf("Address of int &a:                             %p\n", &a);
    printf("value of a:                                    %d\n\n", a);

    printf("Address where p points to via (void *)p:       %p\n", (void *)p);
    printf("Value that *p points to via *p:                %d\n", *p);
    printf("Address of *p itself via (void *)&p:           %p\n\n", (void *)&p);

    printf("Address where pp points to via (void *)pp:     %p\n", (void *)pp);
    printf("Value that **pp points to via **pp:            %d\n", **pp);
    printf("Address of **pp itself via (void *)&pp:        %p\n\n", (void *)&pp);

    printf("Address where ppp points to via (void *)ppp:   %p\n", (void *)ppp);
    printf("Value that ***ppp points to via ***ppp:        %d\n", ***ppp);
    printf("Address of ***ppp itself via (void *)&ppp:     %p\n\n", (void *)&ppp);

    printf("Address where pppp points to via (void *)pppp: %p\n", (void *)pppp);
    printf("Value that ****pppp points to via ****pppp:    %d\n", ****pppp);
    printf("Address of ****pppp itself via (void *)&pppp:  %p\n", (void *)&pppp);

    return EXIT_SUCCESS;
}

Output:


Address of int &a:                             0x7fff08d1c67c
value of a:                                    42

Address where p points to via (void *)p:       0x7fff08d1c67c
Value that *p points to via *p:                42
Address of *p itself via (void *)&p:           0x7fff08d1c670

Address where pp points to via (void *)pp:     0x7fff08d1c670
Value that **pp points to via **pp:            42
Address of **pp itself via (void *)&pp:        0x7fff08d1c668

Address where ppp points to via (void *)ppp:   0x7fff08d1c668
Value that ***ppp points to via ***ppp:        42
Address of ***ppp itself via (void *)&ppp:     0x7fff08d1c660

Address where pppp points to via (void *)pppp: 0x7fff08d1c660
Value that ****pppp points to via ****pppp:    42
Address of ****pppp itself via (void *)&pppp:  0x7fff08d1c658
like image 839
lord.garbage Avatar asked May 12 '15 06:05

lord.garbage


People also ask

How do you print the value a pointer points to?

You can print a pointer value using printf with the %p format specifier. To do so, you should convert the pointer to type void * first using a cast (see below for void * pointers), although on machines that don't have different representations for different pointer types, this may not be necessary.

Does a pointer point to an address or a value?

Put another way, the pointer does not hold a value in the traditional sense; instead, it holds the address of another variable. A pointer "points to" that other variable by holding a copy of its address. Because a pointer holds an address rather than a value, it has two parts. The pointer itself holds the address.

How do you get the address of a pointer to a pointer?

Using a Pointer: To access address of a variable to a pointer, we use the unary operator & (ampersand) that returns the address of that variable. For example &x gives us address of variable x.

How do you print the address of a pointer in C++?

How do I print the address stored in the pointer in C++? int *ptr = &var; printf("%p", ptr); That will print the address stored in ptr will be printed.


Video Answer


1 Answers

Your code is mostly correct: you understand that printf prints the value of pointers with the %p conversion specifier. The actual output is implementation specific but can be parsed back into a pointer value by scanf with the same %p specifier.

There is one small detail you got wrong in printf("Address of int &a: %p\n", &a);: pointers should always be converted to void * when passed to printf as the value to convert for the %p specifier. The reason for this is subtle: on some architectures, pointers to different types may have a different representation, including a different size, and may be passed to printf in a different way. Converting the pointer to void * ensures that it will be passed in the form and manner expected by the printf function.

This conversion is not automatic as printf takes a variable number of arguments of different types, these arguments are passed in a manner specific to vararg functions: for instance float values are converted to and passed as double, but various pointer types are not converted to void *, so you must write this conversion explicitly with a (void *) cast.

Examples of architectures with different pointer representations tend to be less popular nowadays, but older programmers may remember the days of near and far pointers and the various memory models where function and data pointers had a different size.

like image 160
chqrlie Avatar answered Oct 05 '22 12:10

chqrlie