Check if a pointer points to allocated memory on the heap
I want to know if a pointer points to a piece of memory allocated with malloc/new. I realize that the answer开发者_如何学JAVA for an arbitrary address is "No you can't" but I do think it is possible to override malloc/free and keep track of allocated memory ranges.
Do you know a memory management library providing this specific tool?
Do you know something for production code?Valgrind is great, but it is too much instrumentation (slow) and as Will said we don't want to use Valgrind like this (making the soft crash is good enough).
Mudflap is a very good solution, but dedicated to GCC, and sadly, a check does not simply return a boolean (see my answer below). Note that checking that memory writes are legal is a security issue. So looking for performance is motivated.A proof it probably cannot be usefully done:
char * p1 = malloc(1);
free( p1 );
char * p2 = malloc(1); // probably allocates same block as first malloc
Now both p1 and p2 point at same memory on heap, but only p2 is valid.
There's no standard way to do this, but various malloc debugging tools may have a way of doing it. For example, if you use valgrind, you can use VALGRIND_CHECK_MEM_IS_ADDRESSABLE
to check this and related things
You can do this yourself, if performance is not a real issue for your application:
Define MyMalloc(...) and MyFree(...) in which, along with calling malloc/free, you update a (ordered)list of pairs {address -- the result of malloc, blockSize -- the amt of memory requested }. Then when you need to check a pointer p, you look for a pair satisfying: address <= p <= address + blockSize.
Other conditions could/should be checked, if you want to actually use that pointer, this will only tell if an address is in use or not.
Mudflap (for gcc) seems very sweet. You have to compile your soft with but it will check any wrong pointer access (heap/stack/static). It is designed to work for production code with slowdown estimated between x1.5 to x5. You can also disable check at read access for speedup.
User check can be performed using
void __mf_check (void *ptr, __mf_size_t sz, int type, const char *location)
Calling this function results to: nothing, fork to gdb, segv or abort depending on environment parameters.
You can use LD_PRELOAD, and wrap malloc inside your own function.
See our CheckPointer tool, which will check every pointer access for validity. Its not particularly fast, but it will catch errors that even Valgrind wont catch (e.g., pointers to deallocated stack frames, etc.)
Another answer to this question shows a case where doing pure memory range checking on pointer validity would fail to detect a problem. He's sort of right, in that if only have memory range addresses you can't reliably check that a reallocated block of store is misused. This is called a temporal error. By associating the allocation event with the memory block as well as the range, you can detect this. And Checkpointer does this, and will detect the error.
Memory allocations have an (virtual) address and a length.
The pointer only contains the address.
If you track the length separately, you can check its contained, e.g.:
int check_contained(const char* src,size_t srclen,const char* sub,size_t sublen) {
return (sub >= src) && (sub+sublen < src+srclen);
}
Symbian has an AllocLen
function, but there's no POSIX nor win32 equivalent.
I did something similar, but can't remember how exactly it was coded and i don't have the code at hand.
But the basic idea was to override the new
and delete
for a base class. In new
a static flag was set (e.g. bool inDynamicAlloc=true
). This flag is questioned in the constructor of the base class.
When it was true, the object was allocated on the heap, on the stack otherwise.
The constructor resets the flag afterwards.
Hope this helps.
You could use the same techniques that a conservative garbage collector uses to determine if a pointer-like object points to the heap or not. Indeed you could probably crib the source code from bdwgc itself. This would be a non-trivial task, but it would be something you could control and port as needed. (Much of the porting work has already been done, in fact.)
精彩评论