Reputation: 780
First of all I am not very familiar with the stack and heap.
In a lot of programs I see that pointers are checked for NULL
. But that doesn't prevent a crazy address like 0x002011
to be passed.
My question: is there "safe" address interval, that I can check a pointer belongs to and be reasonably sure it's valid, before dereferencing it?
Upvotes: 2
Views: 559
Reputation: 2218
No, For a pointer any value other than zero, could be a valid address. Therefore traditionally programmers have used NULL as the default invlaid value for a pointer.
However, if you are devloping a library where you need this facility then you can one of the following
OR
Note: If performance is the issue then you can have a memory manager running in two modes, i.e. release and debug. Chuck the additional checking in the release version.
Opencore (in Android) does something similar to second approach.
Shash316
Upvotes: 0
Reputation: 7778
In Windows you could try using VirtualQuery
function. It accepts a pointer (lpAddress) you want to test and returns the information about the page that contains the address, if it is a valid one.
If lpAddress specifies an address above the highest memory address accessible to the process, the function fails with ERROR_INVALID_PARAMETER.
This question might give you some starting point on Linux: Is there a better way than parsing /proc/self/maps to figure out memory protection?
Upvotes: 0
Reputation:
Everything except NULL
that comes out of malloc
and friends is a valid pointer, however crazy its value may seem to you. In fact, 0x002011
may be a perfectly valid pointer on some computers (although probably not modern-day desktops).
And a whole lot of pointers to properly-aligned, "sane-looking" addresses that still don't belong to your program. If you don't leave pointers uninitialized and don't manually set them to bullshit values, the only invalid pointer you'll have to watch out for is NULL
. Alternatively, if this is for library code: Don't try to do this for your users, as you can't (if the above wasn't explicit enough), and it's their job anyway.
Upvotes: 2
Reputation: 215577
No, and this is why checking pointers against NULL, except when you have defined and documented that a function accepts NULL and attributes a special meaning to it, is utterly nonsensical. C does not make it possible to write functions which accept pointers but which are robust against the caller breaking the contract. If you don't like this, either don't use pointers or don't use C.
Upvotes: 0
Reputation: 9681
There's no way, as others have said.
But if there would be a way to know which addresses are in the address space of a process, then you could have a clue (if the address is "inside", it is not surely a good valid pointer; but if it is outside, for sure it is not valid).
Some possible checks are system dependent (the previous sentence too, indeed, assumes a specific "set" of modern systems); e.g. on many machines addresses must be word-aligned or alike, so that if you have an odd address (for a non-byte datum), you can suppose it is not valid pointer.
Though, these and other "reasonings" are not reliable (nor portable).
Upvotes: 0
Reputation: 339
There's another case that hasn't been addressed here: writing a library function where you have no control over the parameters that are passed in and you want to ensure that your function returns a "bad pointer" type of error rather than crashing if a pointer to an invalid address is used.
If that's the case, then I think there are OS-specific functions that can give you the valid address range of the current process. You will also need to consider whether the address's alignment is valid for the data type being passed. E.g., if a 4-byte integer value can legally reside at an odd address where address%4 != 0.
Note that even if you take these precautions, there's still no guarantee that the caller won't pass a legal pointer to invalid data. The bottom line is that you can't fix a bug in the calling code.
Upvotes: 2
Reputation: 54634
A pointer is an implementation detail, not a contextual type. Therefore, "valid pointer value" is not a universal property of pointers; it is a property of the context in which the pointer is being used (or the abstraction the pointer is representing). For example, a pointer that points to something on a thread's stack is not a valid pointer to pass to free(...)
. If you can express the context in which a pointer is valid, then it is simply a matter of enumerating or matching against all pointers that are valid within that context to determine whether a pointer is valid (again, within that context).
Upvotes: 1
Reputation: 15353
No, that is not the right way to do things.
You should instead figure out why those crazy addresses are being passed in the first place. You should always either be passing a valid pointer that you've used new or malloc (or some variant of those) to create, or you should be passing the address of stack allocated objects.
Upvotes: 1
Reputation: 613511
NULL
is a special value that is guaranteed to be an invalid pointer. Any other value could be valid.
Upvotes: 3
Reputation: 500893
No, there isn't a (portable and reliable) way to detect whether a pointer is good.
Upvotes: 1
Reputation: 15164
No, there is not. If possible, use references that should always point to valid memory. Pointers are dangerous from their nature and that's why the higher level languages such as Java omit them altogether.
Actually, not even NULL is guaranteed to point to an invalid memory. It's just a convention that's being held but not backed by any standard AFAIK.
Upvotes: 0
Reputation: 20282
No. Make sure to initialize pointers to NULL when creating a new variable, and then only change the value with malloc
(when C) or new
(when C++) or other allocating functions (or assigning to another valid pointer or NULL). Set back to NULL after free
and delete
respectively.
Upvotes: 8