Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if a pointer points to the heap or the stack?

People also ask

Do pointers point to stack or heap?

Pointer is allocated on the stack and the object it is pointing to is allocated on the heap.

Does pointer always point to heap?

A pointer can point to any object, regardless of whether it resides on a "stack", on a "heap" or on same "fixed" memory, and regardless of whether it is a "global variable" or a "local variable".

Can a pointer point to the stack?

(And, yes, if you pull out a plate from somewhere with the stack, you will probably break something.) There are two fundamental operations on a stack: push data-item. This causes the data-item to be placed on the top of the stack and moves the stack pointer to point to this latest item.

Where do pointers point to?

Pointers can point to any addressable memory. This means they cannot point to registers. The type of memory is anything that is memory-mapped, so this could be RAM or ROM for example, or even a file etc. Basically, anything that can be identified my an address.


There is no way of doing this - and if you need to do it, there is something wrong with your design. There is a discussion of why you can't do this in More Effective C++.


In the general case, you're out of luck, I'm afraid - since pointers can have any value, there's no way to tell them apart. If you had knowledge of your stack start address and size (from your TCB in an embedded operating system, for example), you might be able to do it. Something like:

stackBase = myTCB->stackBase;
stackSize = myTCB->stackSize;

if ((ptrStack < stackBase) && (ptrStack > (stackBase - stackSize)))
    isStackPointer1 = TRUE;

The only "good" solution I can think of is to overload operator new for that class and track it. Something like this (brain compiled code):

class T {
public:    
    void *operator new(size_t n) {
        void *p = ::operator new(n);
        heap_track().insert(p);
        return p;
    }

    void operator delete(void* p) {
        heap_track().erase(p);
        ::operator delete(p);
    }

private:

    // a function to avoid static initialization order fiasco
    static std::set<void*>& heap_track() {
        static std::set<void*> s_;
        return s_;
    }

public:
    static bool is_heap(void *p) {
        return heap_track().find(p) != heap_track().end();
    }
};

Then you can do stuff like this:

T *x = new X;
if(T::is_heap(x)) {
    delete x;
}

However, I would advise against a design which requires you to be able to ask if something was allocated on the heap.


Well, get out your assembler book, and compare your pointer's address to the stack-pointer:

int64_t x = 0;
asm("movq %%rsp, %0;" : "=r" (x) );
if ( myPtr < x ) {
   ...in heap...
}

Now x would contain the address to which you'll have to compare your pointer to. Note that it will not work for memory allocated in another thread, since it will have its own stack.


here it is, works for MSVC:

#define isheap(x, res) {   \
void* vesp, *vebp;     \
_asm {mov vesp, esp};   \
_asm {mov vebp, ebp};    \
res = !(x < vebp && x >= vesp); }

int si;

void func()
{
    int i;
    bool b1;
    bool b2;
    isheap(&i, b1); 
    isheap(&si, b2);
    return;
}

it is a bit ugly, but works. Works only for local variables. If you pass stack pointer from calling function this macro will return true (means it is heap)


First, why do you need to know this? What real problem are you trying to solve?

The only way I'm aware of to make this sort of determination would be to overload global operator new and operator delete. Then you can ask your memory manager if a pointer belongs to it (the heap) or not (stack or global data).