* glibc detected ./load: double free or corruption (!prev): ADDRESS **
使用 glibc 时,它怎么知道我在双重释放?它会跟踪我分配和释放的所有内容吗?它是否包含在元数据中,例如 free 如何知道要释放多少空间(如何 free 知道要释放多少空间?)
* glibc detected ./load: double free or corruption (!prev): ADDRESS **
使用 glibc 时,它怎么知道我在双重释放?它会跟踪我分配和释放的所有内容吗?它是否包含在元数据中,例如 free 如何知道要释放多少空间(如何 free 知道要释放多少空间?)
对于每个分配,内存管理器都会保留一些“标题”(很可能是树节点或链表)。当您通过释放某些不包含有效标头的东西时 - 好吧,它无法正确释放。至于这些信息被保存在哪里——这取决于实现,但通常它放置在你从 malloc 获得的地址之前——然而,大小和结构很可能是未知的,但至少它给出了一个想法,这个标头可以多么容易被破坏/损坏/覆盖/等。
When you malloc something, you get a pointer on a memory bloc. You already know that ^^. The memory management also reserve an (hidden) header before* your bloc (which tracks the bloc size for instance) When you free your pointer, the header is red to check if it is a valid pointer. The free operation also erase the header. If you free twice, the header will no longer be valid on the second free. Hence the detection.
The C language standard says that freeing a pointer a second time is undefined behavior. What you see in glibc is one particular case of this undefined behavior--a helpful one--where a message is issued. Most allocators keep track of what is allocated and up to a certain amount it can keep track of what has been freed. But you cannot count on this behavior.
A C program is also allowed to silently crash or ignore the situation (or any other action it deems necessary).
分配的内存或确实具有分配的元数据,用于malloc()
取消分配分配的内存。calloc()
realloc()
free()
但是,不应对如何或是否检测到双重释放做出任何假设,因为该行为在标准中未定义,如下所述。
free()
释放由 指向的内存空间ptr
,该空间必须由先前的调用返回malloc()
,calloc()
或realloc()
。否则,或者如果free(ptr)
之前已经调用过,则会发生未定义的行为。如果 ptr 为NULL
,则不执行任何操作。