"Safe" pointer values interval?

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

Answers (12)

Shash316
Shash316

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

  1. Allocate the memory needed by the library in the beginning. (Assuming you know the requirement beforehand). Use Custom Memory Manager which would use this chunk of memory to service memory allocation and free requests by the library. Any address which is beyond allocated memory ( { start address, start adress + size}) is an invalid pointer.

OR

  1. Develop custom memory manager, which keeps track of memory chunks allocated to different modules of the library. To check pointer validity it goes through its internal table to see if such a memory has been allocated or not.

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

Vinicius Kamakura
Vinicius Kamakura

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

user395760
user395760

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

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

ShinTakezou
ShinTakezou

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

Dave
Dave

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

MSN
MSN

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

Alex
Alex

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

David Heffernan
David Heffernan

Reputation: 613511

NULL is a special value that is guaranteed to be an invalid pointer. Any other value could be valid.

Upvotes: 3

NPE
NPE

Reputation: 500893

No, there isn't a (portable and reliable) way to detect whether a pointer is good.

Upvotes: 1

Karel Petranek
Karel Petranek

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

littleadv
littleadv

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

Related Questions