Prev: performance of hash_map in combination with strings on vstudio 2003
Next: Dot operator Overloading
From: pfultz2 on 31 Mar 2010 04:39 I want detect if a pointer is pointing to memory on the heap or the stack, so I came up with this approach: bool isOnHeap(void * p) { int i = 0; int * s = &i; return (p > s); } I dont if this is the best or most portable way to do it. And im not sure how well it works for static and global variables, do they start on the end of memory? or at the begining? The reason why i want to do this is need to delete pointers sometimes, and some of them point to memory on the stack, so therefore i dont want to delete them, I could use type erasure and create a seperate class to handle the memory and use some form of custom deallocators, but then it would either cost me an extra pointer or double dereferencing, and i was trying to think of a neater way to do it. thanks. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Sujal on 31 Mar 2010 23:06 On Apr 1, 12:39 am, pfultz2 <pful...(a)yahoo.com> wrote: > I want detect if a pointer is pointing to memory on the heap or the > stack, so I came up with this approach: > > bool isOnHeap(void * p) > { > int i = 0; > int * s = &i; > return (p > s); > > } > > I dont if this is the best or most portable way to do it. And im not > sure how well it works for static and global variables, do they start > on the end of memory? or at the begining? The reason why i want to do > this is need to delete pointers sometimes, and some of them point to > memory on the stack, so therefore i dont want to delete them, I could > use type erasure and create a seperate class to handle the memory and > use some form of custom deallocators, but then it would either cost me > an extra pointer or double dereferencing, and i was trying to think of > a neater way to do it. thanks. { edits: quoted banner removed. please keep readers in mind when quoting. -mod } Hi, I don't think, the approach you are using is correct. It is not portable code. Different architecture using different type to handle stack and Heap area. That is totally OS architecture dependent. BTW, As you also asked about where static/global variables are stored then answer is they are stored in BSS area which is part of Data segment. Constants are generally stored in TEXT area or Code segment (Depends upon compiler). C/C++ standard does not talk that any of these types of variable to be stored anywhere specifically. thanks, Sujal Sheth -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Martin B. on 31 Mar 2010 23:04 pfultz2 wrote: > I want detect if a pointer is pointing to memory on the heap or the > stack, so I came up with this approach: > > bool isOnHeap(void * p) > { > int i = 0; > int * s = &i; > return (p > s); > } > > I dont if this is the best or most portable way to do it. And im not > sure how well it works for static and global variables, do they start > on the end of memory? or at the begining? The reason why i want to do > this is need to delete pointers sometimes, and some of them point to > memory on the stack, so therefore i dont want to delete them ... This does not work! I'm not even aware of any non-portable (say Windows specific) way to determine where an arbitrary pointer value belongs. (There is the HeapValidate function but I'm not convinced that it would work.) cheers, Martin -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 31 Mar 2010 23:03 On 31 Mar, 20:39, pfultz2 <pful...(a)yahoo.com> wrote: > I want detect if a pointer is pointing to memory on the heap or the > stack, so I came up with this approach: > > bool isOnHeap(void * p) > { > int i = 0; > int * s = &i; > return (p > s); > > } > > I dont if this is the best or most portable way to do it. And im not > sure how well it works for static and global variables, do they start > on the end of memory? or at the begining? The reason why i want to do > this is need to delete pointers sometimes, and some of them point to > memory on the stack, so therefore i dont want to delete them, I could > use type erasure and create a seperate class to handle the memory and > use some form of custom deallocators, but then it would either cost me > an extra pointer or double dereferencing, and i was trying to think of > a neater way to do it. thanks. This is such a bad idea I checked the date to make sure it wasn't posted today - April first. Not only is it not portable it is fundamentally a bad design. Memory problems are best avoided by only deleting objects in the class that allocates them. If you realy want to go down this route then I would suggest a smart pointer that explicitly knows whether or not the object should be deleted or not (via a ctor parameter) - the only overhead is an extra bool. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: George Neuner on 31 Mar 2010 23:03 On Wed, 31 Mar 2010 13:39:59 CST, pfultz2 <pfultz2(a)yahoo.com> wrote: >I want detect if a pointer is pointing to memory on the heap or the >stack, so I came up with this approach: > >bool isOnHeap(void * p) >{ > int i = 0; > int * s = &i; > return (p > s); >} > >I dont if this is the best or most portable way to do it. And im not >sure how well it works for static and global variables, do they start >on the end of memory? or at the begining? The reason why i want to do >this is need to delete pointers sometimes, and some of them point to >memory on the stack, so therefore i dont want to delete them, I could >use type erasure and create a seperate class to handle the memory and >use some form of custom deallocators, but then it would either cost me >an extra pointer or double dereferencing, and i was trying to think of >a neater way to do it. thanks. In general there's no portable way to do it because there is no standard program memory layout. What you can do, though, is assume that the stack is contiguous, determine its address range and then see whether the target address is within the range. Something like: ******************* void* stack_base; bool ptr_in_stack( const void* target ) { bool retval; int here; void *stack_top = &here; if ( stack_base > stack_top ) // stack grows down retval = (stack_base > target) && (target >= stack_top); else // stack grows up retval = (stack_base <= target) && (target < stack_top); return retval; } int main( void ) { int here; stack_base = &here; : return 0; } ******************* The stack check works on Unix/Linux and Windows because their stacks are contiguous - but there may be other platforms for which it won't work (although I've yet to meet such a platform). Note that a false result (not in stack) doesn't actually mean the target address is within the heap ... it could be a code address or outside the process's address space entirely. To check that a pointer is within the heap on Unix/Linux you can do something similar to the stack check. sbrk(0) will give you the high end of the heap, but there isn't any good way to get the low end. An approximation can be found by taking the highest address from among your global variables (the dynamic heap starts somewhere above the globals), but to be more accurate you'd need to look into the workings of your C++ runtime allocator. You *cannot* simply malloc()/new something at the beginning of the program and assume that it will be at the low end of the heap. ******************* void* heap_base; bool ptr_in_heap( const void* target ) { void *heap_top = sbrk(0); return (heap_base <= target) && (target < heap_top); } ******************* Windows is more difficult because processes may have multiple heaps - each attached DLL may have its own heap and the program itself may have created additional ones beyond the default heap. However, Windows is also more helpful because it provides standard functions for examining the heaps. The following code works for Win32, for Win64 you need to change it to use the appropriate structures for 64-bit: ******************* #include <windows.h> #include <Tlhelp32.h> bool ptr_in_heap( const void* target, const int objectSize = 1 ) { HANDLE snapshot; HEAPLIST32 theHeap; HEAPENTRY32 theBlock; DWORD pid; BOOL moreHeaps, moreBlocks; if ( IsBadReadPtr( target, objectSize ) ) { return false; } pid = GetProcessId( GetCurrentProcess() ); snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPHEAPLIST, pid ); theHeap.dwSize = sizeof(theHeap); moreHeaps = Heap32ListFirst( snapshot, &theHeap ); while ( moreHeaps ) { theBlock.dwSize = sizeof(theBlock); moreBlocks = Heap32First( &theBlock, theHeap.th32ProcessID, theHeap.th32HeapID ); while ( moreBlocks ) { char* lo = (char*) theBlock.dwAddress; char* hi = lo + theBlock.dwBlockSize; if ((lo <= target) && (target <= hi)) { return true; } moreBlocks = Heap32Next( &theBlock ); } moreHeaps = Heap32ListNext( snapshot, &theHeap ); } return false; } ******************* Finally, note that none of this tells you whether the target address is a valid program object ... all you can safely determine is whether the address is legal. George -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 3 4 5 6 Prev: performance of hash_map in combination with strings on vstudio 2003 Next: Dot operator Overloading |