原理

先说明一下,unlink是只有双链表才有的机制,也就是说只有small bins和large bins存在,而fastbins由于是双链表,是不存在unlink的

没有检测的情况下

按照wiki中最早没有检测的情况讲解unlink

这是wiki中的图,BK是P chunk前的chunk,FD是P chunk后的chunk 此时的堆情况:

P->fd=FD_prev_addr
P->bk=BK_prev_addr
BK->fd=P_prev_addr
FD->bk=P_prev_addr

假设进行了一次unlink(先不要管合并)

BK->fd=FD_prev_addr
FD->bk=BK_prev_addr

简单来讲就是BK的下一个chunk变成了FD,FD的上一个chunk变成了BK,而被free的chunk则与BK或者FD中处于free状态的合并了 但是这只是small bins的情况,large bins还需要额外注意

fd_nextsize

bk_nextsize

因为fast bins和small bins每一个bins组中chunk大小相同,但是large bins不一定

详解

#include<stdio.h>
void main(){
    long *abgl1 = malloc(0x80);
    long *FD = malloc(0x80);
    long *abgl3 = malloc(0x80);
    long *P = malloc(0x80);
    long *abgl5 = malloc(0x80);
    long *BK = malloc(0x80);
    long *abgl7 = malloc(0x80);

    free(FD);
    free(P);
    free(BK);

    return 0;
}

 ////gcc -g test.c -o test -Wl,-rpath='/home/abgl/Desktop/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/',-dynamic-linker='home/abgl/Desktop/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so'
//因为我这里Ubuntu版本高,所以编译时用低版本glibc

 //代码来自https://blog.csdn.net/qq_41202237/article/details/108481889

 //为方便理解进行修改

在10和15行设断点