Can looking at freed memory cause an access violat

2020-04-11 07:24发布

Can accessing (for read only) memory freed cause an access violation, and, if so, under what circumstances?

8条回答
手持菜刀,她持情操
2楼-- · 2020-04-11 07:59

We can access it but not encouraged. for example

void main()
{
    char *str, *ptr;  
    str = (char *)malloc(10);
    ptr = str;
    strcpy(str, "Hello");
    printf("%s", str);
    free(str);
    printf("%s", ptr);      
}
查看更多
唯我独甜
3楼-- · 2020-04-11 08:02

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().

查看更多
狗以群分
4楼-- · 2020-04-11 08:10

On Windows: Managing Virtual Memory in Win32

Free, Reserved, and Committed Virtual Memory

Every address in a process can be thought of as either free, reserved, or committed at any given time. A process begins with all addresses free, meaning they are free to be committed to memory or reserved for future use. Before any free address may be used, it must first be allocated as reserved or committed. Attempting to access an address that is either reserved or free generates an access violation exception.

查看更多
做个烂人
5楼-- · 2020-04-11 08:12

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.

查看更多
时光不老,我们不散
6楼-- · 2020-04-11 08:20

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.

查看更多
我只想做你的唯一
7楼-- · 2020-04-11 08:21

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 or realloc 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.

查看更多
登录 后发表回答