讲C的书多告诉我们malloc出的内存用完要free掉,为了避免出现野指针,还要将指针置为NULL。
今天做了个小实验,从内存的角度看free()究竟做了什么、为什么最后要把指针设为NULL。
-----
看下面的例子:
---
update:
重新翻了下K&R,发现书上说的也确实如此!
下面是stackoverflow上的一个回答(地址:http://stackoverflow.com/questions/2468853/freeing-memory-twice)
Freeing memory does not set the pointer to null. The pointer remains pointing to the memory it used to own, but which has now had ownership transferred back to the heap manager.
The heap manager may have since reallocated the memory your stale pointer is pointing to.
Freeing it again is not the same as saying free(NULL), and will result in undefined behavior.
我的理解:
在第一次free()调用后,堆管理器将我们free()的内存和相邻的块重新组成了新的更大的块,以便下次malloc()调用,这时,这块内存已经不属于malloc出的内存了,对非malloc出的内存进行free,其结果是未定义的(我们这里是double free crash)。
--
update:
参考:http://code.woboq.org/userspace/glibc/malloc/malloc.c.html
malloc出来的内存块结构:
1. An allocated chunk looks like this:
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
空闲块结构:
2. Free chunks are stored in circular doubly-linked lists, and look like this:
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`head:' | Size of chunk, in bytes |P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Forward pointer to next chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Back pointer to previous chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused space (may be 0 bytes long) .
. .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
第一次free:
第二次free:
看double free后出现了2块同样的chunk,堆管理器显然是不能同意的!
原文:http://blog.youkuaiyun.com/wusuopubupt/article/details/39006561