Reputation: 205
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
Reputation: 208353
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
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
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
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