4

I'm a newcomer in C++. I tested a unique pointer on my PC: I thought it would be allocated on the heap, but it shows on the stack instead. This confused me. Does a unique pointer allocate memory on the heap or stack?

    #include <memory>
    #include <stdio.h>

    void RawPointer()
    {
        int *raw = new int;// create a raw pointer on the heap
        printf("raw address: %p\n", raw);
        *raw = 1; // assign a value
        delete raw; // delete the resource again
    }

    void UniquePointer()
    {
        std::unique_ptr<int> unique(new int);// create a unique pointer on the stack
        *unique = 2; // assign a value
        // delete is not neccessary
        printf("unique pointer address: %p\n", &unique); 
    }

    int main(){
        RawPointer();
        UniquePointer();
    }

and it comes in shell:

    raw address: 0x555cd7435e70
    unique pointer address: 0x7ffcd17f38b0

thanks bros,

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
kit_J
  • 63
  • 3
  • 1
    A unique pointer did not allocate anything. It only keeps a pointer to something, which can be on the heap or on the stack. And the unique pointer itself can be on stack or on heap. Allocating with new means heap allocation. – Klaus May 16 '20 at 09:28
  • " but it shows on the stack instead" what exactly is "it" ? Its not clear how you come to your conclusion. There is a difference between the `unique_ptr` and the pointer it encapsulates, in case that is causing confusion – 463035818_is_not_an_ai May 16 '20 at 09:29
  • thanks, that means i could consider unique as a class, inside the int pointer point to the heap. am i right? – kit_J May 16 '20 at 09:33

2 Answers2

1

What you are printing in your UniquePointer function is the address of the std::unique_ptr class object. This class has an internal member that is the actual address of the allocated data.

You can access this actual address using the get() member function, as shown in the code below (which, when I tried, gave me the exact same address as for the raw pointer - though that won't always be the case):

void UniquePointer()
{
    std::unique_ptr<int> unique(new int);// create a unique pointer on the stack
    *unique = 2; // assign a value
    // delete is not neccessary
 // printf("unique pointer address: %p\n", &unique);
    printf("unique pointer address: %p\n", unique.get());
}

Note: The %p format specifier expects a void * pointer as an argument; however, an implicit cast to a void pointer (from a pointer to another type) is well-defined behaviour - see here: void pointers: difference between C and C++.

Feel free to ask for further clarification and/or explanation.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
0

In your example raw and unique are local variables, allocated on the stack, which you can check when printing the address of the variables address.

printf("raw pointer address: %p\n", (void*)&raw);
printf("unique pointer address: %p\n", (void*)&unique);

But the pointers raw and unique can point anywhere. If they point to an object allocated with new, then the pointer points to an object on the heap. Which you can see when printing the pointer value.

printf("raw pointer points to: %p\n", (void*)raw);
printf("unique pointer points to: %p\n", (void*)unique.get());

Please note that I've added a (void*) cast to the pointers I pass to printf because, if I remember correctly, %p requires a void*.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69