Yes, it takes space but just a small one that does not depend on the actual type. It is 8 Bytes on 64-bit platform for example. This address is stored on the stack by the way.
Example:
class foo; // the size of this class is 10 byte
void bar(){
foo* x; // this is just 4 bytes on x86 machine
x=new foo{}; // there is 10 bytes on the heap and the original 4 bytes on the stack
delete x; //we just have now the 4 bytes of the pointer in the stack
}// the pointer is destroyed and nothing left in the heap or in the stack
If you want a better understanding, consider the pointer as a class which has the following design idea :
template <typename T>
class pointer{
public:
void allocate(){
p=new T{};
}
T* p;
};
When you allocate an object of it, you should do this:
pointer<int> my_pointer; // This is obviously a stack object
my_pointer.allocate(); // Now you have allocated memory on heap
P.S. Previous example is so breif and useless. It just for explaining a small idea