2

In "Computer System: A Programmer's Perspective", section 2.1 (page 31), it says:

The value of a pointer in C is the virtual address of the first byte of some block of storage.

To me it sounds like the C pointer's value can take values from 0 to [size of virtual memory - 1]. Is that the case? If yes, I wonder if there is any mechanism that checks if all pointers in a program are assigned with legal values -- values at least 0 and at most [size of virtual memory - 1], and where such mechanism is built in -- in compiler? OS? or somewhere else?

crockeea
  • 21,651
  • 10
  • 48
  • 101
Jay Somedon
  • 1,068
  • 11
  • 27
  • I think it is confirmed by the size of pointer, in 32bit system, size of pointer is 4bytes, and the virtual memory is 2^32, so it is always valid ? – michaeltang Feb 17 '14 at 03:39
  • Legal values are implementation and OS specific. To accomplish what you seek would require a system the literally knows where each pointer is in your running code. Most analyzers look for pointers that *are* valid *because* the byte sequence is a valid memory offset), but there are *very* few platforms (I can only think of one) that actual *know* whether the value stored in a specific place in process memory is (a) a pointer, and (b) holds a valid address. – WhozCraig Feb 17 '14 at 03:42
  • A pointer can take any valid value. But "valid" is qualified many ways. Zero is valid, but 1 most certainly isn't. Some ranges are valid and others not, depending on what address ranges are allocated to the process. Even addresses may be valid and odd not, depending on architectural details. – Hot Licks Feb 17 '14 at 03:43
  • @WhozCraig - Some versions of Java know which specific locations are pointers and which not, but it's pretty much impossible in C. – Hot Licks Feb 17 '14 at 03:44
  • @HotLicks Its difficult, but not impossible, if done at the kernel level. An AS/400 does this (the one platform I could think of), and to say it is remarkable would be an understatement of epic proportion. – WhozCraig Feb 17 '14 at 03:48
  • @WhozCraig - AS/400 "cheats" and has a physical "tag" in each pointer -- an extra bit per quadword that is only set on in pointers. (And, interestingly, the "Classic JVM" on AS/400 did *not* use the tag bits to identify pointers.) – Hot Licks Feb 17 '14 at 03:51
  • @HotLicks heh. never said it wasn't cheating =P I find it hysterical that their JVM didn't use it though. Thats *awesome*. – WhozCraig Feb 17 '14 at 04:08
  • @WhozCraig - It allowed 8-byte pointers, and improved performance over having to deal with the tag. And the tag wasn't needed for security since the JVM provides equivalent security. – Hot Licks Feb 17 '14 at 12:23

3 Answers3

3

There is no process that checks pointers for validity as use of invalid pointers has undefined effects anyway.

Usually it will be impossible for a pointer to hold a value outside of the addressable range as the two will have the same available range — e.g. both will be 32 bit. However some CPUs have rules about pointer alignment that may render some addresses invalid for some types of data. Some runtimes, such as 64-bit Objective-C, which is a strict superset of C, use incorrectly aligned pointers to disguise literal objects as objects on the heap.

There are also some cases where the complete address space is defined by the instruction set to be one thing but is implemented by that specific hardware to be another. An example from history is the original 68000 which defined a 32-bit space but had only 24 address lines. Very early versions of Mac OS used the spare 8 bits for flags describing the block of data, relying on the hardware to ignore them.

So:

  • there's no runtime checking of validity;
  • even if there were, the meaning of validity is often dependent on the specific model of CPU (not just the family) or specific version of the OS (ditto) so as to make checking a less trivial task than you might guess.

In practise what will normally happen if your address is illegal per that hardware but is accessed as though legal is a processor exception.

Tommy
  • 99,986
  • 12
  • 185
  • 204
2

A pointer in C is an abstract object. The only guarantee provided by the C standard is that pointers can point to all the things they need to within C: functions, objects, one past the end of an object, and NULL.

In typical C implementations, pointers can point to any address in virtual memory, and some C implementations deliberately support this in large part. However, there are complications. For example, the value used for NULL may be difficult to use as an address, and converting pointers created for one type to another type may fail (due to alignment problems). Additionally, there are legal non-typical C implementations where pointers do not directly correlate to memory addresses in a normal way.

You should not expect to use pointers to access memory arbitrarily without understanding the rules of the C standard and of the C implementations you use.

There is no mechanism in C which will check if pointers in a program are valid. The programmer is responsible for using them correctly.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

For practical purposes a C pointer is either NULL or a memory address to something else. I've never heard of NULL being anything but zero in real life. If it's a memory address you're not supposed to "care" what the actual number is; just pass it around, dereference it etc.

seand
  • 5,168
  • 1
  • 24
  • 37