Can accessing (for read only) memory freed cause an access violation, and, if so, under what circumstances?
相关问题
- Multiple sockets for clients to connect to
- What uses more memory in c++? An 2 ints or 2 funct
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
We can access it but not encouraged. for example
If you're asking this because you've profiled your code and found that accessing freed memory would provide a significant performance boost, then the answer is very rarely, if the freed block is small. If you want to be sure, provide your own alternative implementation of malloc() and free().
On Windows: Managing Virtual Memory in Win32
freed memory doesn't belong to you anymore, exactly, corresponding physical memory page is out of your process address space which might have been remapped to other process address space already after your freeing, and that address you accessing have not been allocated physical page and do mapping yet; so "Access violation" or "segfault" will happen if access it even for reading only. it is triggered by the processor hardware in general, e.g. GP#, not by OS.
though if the specific physical page which owns your freed memory is still under controlling of your task context, say partial of the page is still used by your process, then "Access violation" or "segfault" may not occur.
Unlikely
Memory managers can theoretically return space to the OS but rarely if ever do so. And without returning the space all the way to the kernel, the MMU will never be involved and so a fault is not possible.
The problem is fragmentation. Allocation of variably-sized blocks is inefficient, and general purpose allocators cannot move allocated blocks around because they don't know what points to what, so they can't coalesce blocks unless they happen to be adjacent.
Measurements indicate that fragmentation overhead tends to be about 50% in steady-state processes, so with every-other-block untouchable it's impossible to return pages unless they are much smaller than blocks, and they generally are not.
Also, the book-keeping challenge of returning pages embedded within the heap is daunting, so most memory managers don't even have the capability, even in the unlikely case that they would have the opportunity.
Finally, the traditional process model was not a sparse object. This kind of low-level software is conservatively developed and lives for a long time. An allocator developed today just might attempt sparse allocation but most subsystems just use whatever is already in the C library, and that is not something that's wise to rewrite casually.
It's certainly allowed to; the C standard says straightforwardly that behavior is undefined if "The value of a pointer that refers to space deallocated by a call to the
free
orrealloc
function is used". In practice, owing to the way OSs work, you're more likely to get garbage than a crash, but quite simply you're not allowed to assume anything about what happens when you invoke undefined behavior.