Mateusz Kowalski
Mateusz Kowalski

Reputation: 205

Memory addressation - zero value

Let's assume we have a following code snippet

int* p = new int[5];

and our code is running in protected mode. Because of it, address located in our p variable is not a physical address but only an address to a part of virtual memory allocated for our application. Of course our system is additionally protected from memory violation attempts.

In these circumstances, is it possible to be given a "zero" address so we would have p = 0 and it would be correct? Of course I'm taking into consideration that value 0 is treated like a nullptr, so it could be misleading if this address would be correct.

In fact, are there any rules telling us what is a legal addressable range?

Of course there is another reason for not be given this value, but I don't know if I'm correct - in C (C++) pointers with zero value are treated in special way, so how would we notice a difference if our pointer points to allocated memory or if it has a value zero because it is a nullptr?

Upvotes: 2

Views: 241

Answers (4)

Yes, in fact part of my question is "whether you can trust that p==0 implies that the allocation failed?".

By default, new throws an exception if it fails to allocate to signal the error, so there is no point in checking the returned value. If you use the no-throw version of new, then you are guaranteed that the value returned will not be nullptr, so the test would be fine.

Now, on the larger question of whether it is safe to use the memory returned, it might or might not. Different OS implementations overcommit on memory, so they will grant more memory to the applications than is physically available, on the assumption that by the time the app might need it, maybe something would have freed somewhere else. With that in mind, beware that if you are asking for a large amount of memory, even if it is allocated to you by the language construct (new) and the OS (allocator implementation underneath), there is no guarantee that you will be able to use it.

Upvotes: 0

Gabe
Gabe

Reputation: 86718

Runtime environments that provide virtual memory for C-based programs generally do not allow 0x00000000 (or anything near it) to be a valid address.

You will have to work hard to get a pointer to have a 0x00000000 value and still be valid! In general this means manually making the OS system calls to map virtual memory (mmap, VirtualAlloc). In some cases the OS has safeguards to prevent mapping that particular page of memory. For example, in some older versions of Windows you had to pass 1 as the address you wanted to map instead of 0, while in newer versions you can only do it if you have a special bit set in kernel mode. On some versions of Linux you must first set mmap_min_addr to 0 before you can map that page.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726599

is it possible to be given a "zero" address so we would have p = 0 and it would be correct?

I think you are mixing up the physical and the logical side of the virtual memory management.

On the logical side, your program is guaranteed to never see a pointer that compares equal to zero:

6.3.2.3 (3) defines integer constant expression 0 and such an expressions cast to (void *) as null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

On the physical side, though, there is no such restriction: there is nothing preventing the virtual memory management system from giving your program a block of memory with the physical address of zero. However, that physical address would never appear at the virtual address matching the value of the pointer constant zero: the physical address is hidden from your program by the virtual memory management system, and the virtual address corresponding to the pointer constant zero is guaranteed not to become allocated to your program by the compiler.

Upvotes: 3

jcoder
jcoder

Reputation: 30035

The constant '0' represents a null pointer. That is not necessarily stored as the literal value 0x00000000 in the pointer though. So in theory you can get 0x00000000 back as your object's address and it would be valid if storing the constant 0 into a pointer stored the null pointer as a different value.

In practice that doesn't happen in any compiler I'm aware of though.

Upvotes: 2

Related Questions