So I have searched on the internet and found that there is no way to find out if a pointer points to dynamically allocated memory or not. The C++ standard itself is silent on this matter. There are however certain "extensions" that exist that help the solve the problem "partially". I have not looked into all of them yet.
C++ book tells me that variables are assigned on stack and heap. Static variables are on stack and dynamic ones are in the heap. Memory in the heap can be allocated and freed as needed. Now shouldn't it be that certain range of addresses for a program is assigned as stack and another chunk as the heap. It should then be possible to get the start and end addresses of these memory ranges. Now we only need to see where the address in pointer lies and we know if it points to dynamically allocated memory or static one.
This is the way I think about it, probably not 100% correct in all cases but the basic concept.
When you code and declare a variable (examples: int or string) or array, that is static memory and the size can't be changed while the program is running. That's why INT for example has a fixed size. Everything else is pretty much dynamic. One example is a vector.
Edit. You can not free static memory while the program is running.
It should then be possible to get the start and end addresses of these memory ranges.
True, you can
Now we only need to see where the address in pointer lies and we know if it points to dynamically allocated memory or static one.
False
For one thing memory use is not always going to be sequential.
When you look at the memory address it's just going to tell you what's stored in it. I don't know how you tell what type it is unless you know what data should be there. There are probably some memory tools out there to give you this information. Static memory should be easier to identify since you should know what's going there but it may be converted.
Now obviously if you can free it, then it's not static.
Now we only need to see where the address in pointer lies and we know if it points to dynamically allocated memory or static one.
Well, you should check to see if the pointer value corresponds to the the stack not. If it is not, then it can be assumed to be dynamic memory. You can get the current stack-size and starting address (on x86, at least) from the ESP and EBP processor registers.
The stack is sequential -- I'm not 100% if that is required, but it is on every platform I've ever used.
Similarly, I don't know if memory addresses are required to be unique (no overlap) but I would have a hard time supporting the case where they weren't.
Regardless, you can't do this in standard C++. Why would you need to know?
The stack is sequential -- I'm not 100% if that is required, but it is on every platform I've ever used.
Both GNU and Clang allow segmented stacks, and of course every thread has its own stack. A program that uses coroutines may perform user-space context switches, after which the stack pointer may point into a dynamically allocated region.
String literals of course are allocated along with other static objects. Numeric literals can usually be encoded in the opcodes, depending on the value and the instruction set. Also, if the address of a numeric symbolic constant is never obtained, the compiler may treat it as if it was a literal.
Hmm -- good to know. But when would that feature be used, and why? Just a space optimization, I guess?
A program that uses coroutines may perform user-space context switches, after which the stack pointer may point into a dynamically allocated region.
Can you explain how coroutines might leave the stack pointer referring to dynamically-allocated memory? Obviously the current context has to be saved somewhere (be it in dynamic memory or not) so that it can be restored at a later point, but that doesn't explain how the stack pointer might refer to memory elsewhere.
The page points out that in the case of a segmented stack, new blocks of stack (the page calls them "stacklets") might be dynamically allocated as required (it would defeat the point if the memory was already available). That answers both my questions.
:)