Ubuntu 16.04 – malloc实现.指向下一个块的指针在哪里?

前端之家收集整理的这篇文章主要介绍了Ubuntu 16.04 – malloc实现.指向下一个块的指针在哪里?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我试图了解glibc中的malloc实现是如何工作的.根据malloc的源代码(glibc 2.23中的malloc.c),空闲内存块具有以下结构.

    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                           |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

通常我们应该能够在gnu调试器(gdb)中看到这个结构.所以我写了以下程序.该程序分配6个大小为64字节的内存块.每个块都填充了memset,因此我们可以在以后轻松查看gdb中的相应块.因为块1,3和6被释放,所以它们应该具有上述结构.由于中间存在已分配的块,因此释放的块不能合并,因此它们通过每个块中的指针组织在双重链表中.

#include dio.h>
#include 

当我在gdb中启动程序并在strcpy行中设置断点时(b4,argv [1]);我们应该能够看到释放的块被组织在一个双链表中.但是gdb输出如下:

gdb-peda$p b1
$11 = 0x602010 ""
gdb-peda$x/62xg 0x602000
0x602000:   0x0000000000000000  0x0000000000000051  
0x602010:   0x0000000000000000  0x4242424242424242   |
0x602020:   0x4242424242424242  0x4242424242424242   | b1 (freed)
0x602030:   0x4242424242424242  0x4242424242424242   |
0x602040:   0x4242424242424242  0x4242424242424242   |
0x602050:   0x0000000000000000  0x0000000000000051
0x602060:   0x4343434343434343  0x4343434343434343   |
0x602070:   0x4343434343434343  0x4343434343434343   | b2 (allocated)
0x602080:   0x4343434343434343  0x4343434343434343   |
0x602090:   0x4343434343434343  0x4343434343434343   |
0x6020a0:   0x0000000000000000  0x0000000000000051
0x6020b0:   0x0000000000602000  0x4444444444444444   | 0x602000 is pointing to b1 (prevIoUs freed block)
0x6020c0:   0x4444444444444444  0x4444444444444444   | b3 (freed)
0x6020d0:   0x4444444444444444  0x4444444444444444   | 
0x6020e0:   0x4444444444444444  0x4444444444444444   |
0x6020f0:   0x0000000000000000  0x0000000000000051
0x602100:   0x0000000000000000  0x0000000000000000   |
0x602110:   0x0000000000000000  0x0000000000000000   | b4 (will be filled trough strcpy(b4,argv[1]);
0x602120:   0x0000000000000000  0x0000000000000000   |
0x602130:   0x0000000000000000  0x0000000000000000   |
0x602140:   0x0000000000000000  0x0000000000000051
0x602150:   0x4545454545454545  0x4545454545454545   |
0x602160:   0x4545454545454545  0x4545454545454545   | b5 (allocated)
0x602170:   0x4545454545454545  0x4545454545454545   |
0x602180:   0x4545454545454545  0x4545454545454545   |
0x602190:   0x0000000000000000  0x0000000000000051
0x6021a0:   0x00000000006020a0  0x4646464646464646   | 0x6020a0 is pointing to b3 (prevIoUs freed block)
0x6021b0:   0x4646464646464646  0x4646464646464646   | b6 (freed)
0x6021c0:   0x4646464646464646  0x4646464646464646   |
0x6021d0:   0x4646464646464646  0x4646464646464646   |
0x6021e0:   0x0000000000000000  0x0000000000020e21

在此输出中,我们可以看到释放的块和指向前一个释放块的后向指针(请参阅输出右侧的注释).但前锋指针和前一块的大小在哪里?

最佳答案
从security.stackexchange交叉发布

根据要释放的块的大小,块被保存在不同类型的块(链表)中:

>未分类垃圾
>小垃圾
>大箱子

如果您有兴趣了解这些垃圾箱的维护方式,建议您查找源代码.但是所有这些箱子中常见的一点是这些列表是双重联系的.所以你的假设是正确的,你应该在释放的块中找到前向和后向指针(也可能是之前的大小字段)

然而,还有另一种称为fastbin的特殊箱.非常小的块(通常在16到80个字节之间,但在不同版本中可能略有不同)保存在这些快速箱中.与常规垃圾箱不同,它们是单独连接的.它们根据它们的大小保存在适当的fastbin中(每个bin包含相同大小的块).可以在LIFO订单中添加删除块,而不是必须遍历列表,从而加快性能.与常规块不同,相邻的fastbin-chunk不会被合并(这当然会导致碎片化,但会更快地释放).这也意味着您不需要前一个块的大小.

程序中的块也可能是其中一个fastbins的一部分.因此,要查看您的期望,请尝试分配和释放更大的内存.

猜你在找的Linux相关文章