Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
glibc&x27的内部运作;s free()_C_Heap_Free_Glibc - Fatal编程技术网

glibc&x27的内部运作;s free()

glibc&x27的内部运作;s free(),c,heap,free,glibc,C,Heap,Free,Glibc,对于Glibc2.15,我在看malloc.c,特别是free()函数,对unlink()宏感到困惑。根据来源,正在使用的区块如下所示: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Size of previous chunk, if allocated +-+-+-+-+-+-+-+-+-+-+-+

对于Glibc2.15,我在看malloc.c,特别是free()函数,对unlink()宏感到困惑。根据来源,正在使用的区块如下所示:

   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Size of previous chunk, if allocated            
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Size of chunk, in bytes                       
     mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  User data starts here...                          .
    .                                                               .
    .             (malloc_usable_size() bytes)                      .
    .                                                               
nextchunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         Size of previous chunk                    
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 `head:'           Size of chunk, in bytes                          
  mem->     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Forward pointer to next chunk in list             
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Back pointer to previous chunk in list            
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Unused space (may be 0 bytes long)                .
    .                                                               .
    .                                                               
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
一个free()'d块如下所示:

   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Size of previous chunk, if allocated            
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Size of chunk, in bytes                       
     mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  User data starts here...                          .
    .                                                               .
    .             (malloc_usable_size() bytes)                      .
    .                                                               
nextchunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         Size of previous chunk                    
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 `head:'           Size of chunk, in bytes                          
  mem->     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Forward pointer to next chunk in list             
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Back pointer to previous chunk in list            
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Unused space (may be 0 bytes long)                .
    .                                                               .
    .                                                               
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
当一个使用过的块是free()时,它将接收到的mem指针作为一个参数,并从中减去一个偏移量,得到一个块指针。在这两者之间有一系列的检查,但是在块没有被映射的情况下,它通常会向前或向后将其与另一个空闲块合并。因为chunk be free()'d已经在一个bin中,所以它只是在该bin中搜索要合并的chunk,对吗?在前向合并的情况下,将调用
unlink()
宏,并将其应用于空闲块()后面的块。我不理解这一点,因为当下一个块(称为“nextchunk”)被取消链接时,会出现以下代码:

    #define unlink(P, BK, FD) {                                            
    FD = P->fd;                                                          
    BK = P->bk;
    .
    .
    .
    FD->bk = BK;                                                       
    BK->fd = FD;
    .
    .
    .
                             }

考虑到BK指向空闲的区块()'d,并且从其结构看,它没有向前或向后指针,如何引用
BK->fd
。我一定错过了代码中fd和bk字段添加到chunk being free()d的部分,但我不知道在哪里。有人能帮忙吗?谢谢。

这一行在被释放的块中创建一个向前指针:

BK->fd = FD;
BK过去是一块用户数据,但现在是一块免费数据,因此允许
malloc
在内存中随意涂鸦

如果有帮助,你可以把它想象成一个联盟:

union {
    struct {
        chunk *fd;
        chunk *bk;
    } freed;
    unsigned char user_data[N];
};
在工会中,您可以向任何工会成员写信,但只能从最近写信的成员那里阅读。因此,当调用
free
时,数据被写入
fd
bk
——这没关系,唯一的结果是
user\u data
现在可能有垃圾。相比之下,当区块包含用户数据(非免费)时,
fd
bk
指针是垃圾,因为它们别名为
user\u data

(从技术上讲,您始终可以读取
用户\u数据
,不管它的别名是什么,因为它是
无符号字符
,但这并不真正相关。)

更新:这是低级C代码。您希望在
malloc
实现中使用低级C代码。字段存在或不存在的想法在低级代码中没有意义,因为我们在不同类型之间进行转换,并允许指针彼此别名

在低级代码中,字段只是内存偏移量。在我的系统上,
fd
字段的偏移量可能为0,
bk
字段的偏移量可能为8或4,具体取决于我编译的体系结构。因此,以下代码:

BK->fd = FD;
这意味着“将值FD写入存储器位置BK+0”。如果您认为
BK->fd
只是内存中的一个位置,它可能会帮助您了解
free
的工作原理。(它实际上不仅仅是内存中的一个位置,因为在编译时还存在类型信息和别名规则。)

理解低级C:如果您想理解低级C代码,那么理解汇编语言将非常有帮助。这不是必要的,但有帮助。学习哪种汇编语言并不重要:x86、MIPS、PowerPC、ARM等等。您不需要学习太多汇编语言,只需要一点点。您不需要学习x86,即使从未使用过MIPS,也可以学习MIPS。(事实上,MIPS可能更容易学习。)

只要学习足够多的汇编代码,就可以将一小段C代码翻译成汇编代码,这样就可以理解它在幕后做什么。上面的一行C代码可能会转换成一行汇编代码,因为它非常简单


在编写C时,尽量不要过多地考虑汇编。在编写C时,编译器编写汇编,这意味着您没有编写汇编。

那么原来是malloc()的块的fd和bk字段是否正确?它们被标记为“用户数据”。但这是否意味着不能将任何数据写入用户数据的前x字节,以便fd和bk不会被覆盖?当区块被传递到
free
时,
free
函数写入
fd
bk
字段。字段与用户数据重叠,但这没关系,因为用户数据不用于释放的块。但是,由于BK=nextchunk->BK BK BK BK BK是指向空闲块顶部的指针()'d,当调用BK->fd=fd时,这不只是“引用”吗字段fd或者它实际上是在BK中创建fd并将其设置为fd?Mabye我应该看看在调用malloc创建现在可用的内存时创建的初始结构。我确实了解x86程序集,并且理解代码中“存在”的概念,但是当引用了一个没有意义的偏移量时,这是行不通的。因此,当空闲的块()是malloc()'d时,它的结构必须在某个地方定义它…我将再次检查源代码.1+“当您编写C时,编译器正在编写程序集,这意味着您没有编写程序集。”