Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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
malloc存储其元数据_C_Malloc_Details - Fatal编程技术网

malloc存储其元数据

malloc存储其元数据,c,malloc,details,C,Malloc,Details,令人惊讶的是,尽管数据类型不同,但两个程序给出的两个指针之间的差异是相同的 malloc到底是如何存储其元数据的,这是我通过这个小实验试图找到的 方案1: int main () { char *i,*j; i=(char*)malloc (sizeof(char)); j=(char*)malloc (sizeof(char)); printf ("%x\n",i); printf ("%x\n",j); return 0; } 输出: 7100

令人惊讶的是,尽管数据类型不同,但两个程序给出的两个指针之间的差异是相同的

malloc到底是如何存储其元数据的,这是我通过这个小实验试图找到的

方案1:

int main ()
{
    char *i,*j;

    i=(char*)malloc (sizeof(char));
    j=(char*)malloc (sizeof(char));

    printf ("%x\n",i);

    printf ("%x\n",j);
return 0;
}
输出:

710010
710030
方案2:

int main ()
{
    int *i,*j;

    i=(int*)malloc (sizeof(int));
    j=(int*)malloc (sizeof(int));

    printf ("%x\n",i);

    printf ("%x\n",j);
return 0;
}
输出:

16b8010
16b8030
在这个项目之前我的想法是:

| meta data of i | memory space of i | meta data of j | memory space of j |
但结果并不支持这一理论……

malloc
“舍入”分配到库在编译时设置的方便大小。这会导致后续分配和解除分配的内存碎片少于创建分配以完全匹配请求时的内存碎片

malloc
存储其元数据的位置实际上并不是这两个值相差0x20的原因。但是你可以阅读一种实现malloc的方法(还有朋友);请特别参见幻灯片16和28

想象一下字符串操作程序的情况,其中大量不同大小的分配以“随机”顺序发生。微小的“剩余”块会很快发展起来,在使用过的块之间留下完全无用的内存字节
malloc
通过以最小大小的倍数满足所有内存请求(在本例中显然是0x20)来防止这种情况。(好的,从技术上讲,如果您请求0x1E字节,将有2个字节的“浪费”请求后剩余和未使用的空间。由于
malloc
分配的是0x20字节而不是0x1E,但永远不会剩下2字节的片段。这非常好,因为
malloc
的元日期肯定大于2字节,因此甚至无法跟踪这些字节。)

malloc
“舍入”分配到库编译时设置的方便大小。这会导致后续分配和解除分配的内存碎片少于创建分配以完全匹配请求时的内存碎片

malloc
存储其元数据的位置实际上并不是这两个值相差0x20的原因。但是你可以阅读一种实现malloc的方法(还有朋友);请特别参见幻灯片16和28


想象一下字符串操作程序的情况,其中大量不同大小的分配以“随机”顺序发生。微小的“剩余”块会很快发展起来,在使用过的块之间留下完全无用的内存字节
malloc
通过以最小大小的倍数满足所有内存请求(在本例中显然是0x20)来防止这种情况。(好的,从技术上讲,如果您请求0x1E字节,将有2个字节的“浪费”请求后剩余和未使用的空间。由于
malloc
分配的是0x20字节而不是0x1E,但永远不会剩下2字节的片段。这非常好,因为
malloc
的元日期肯定大于2字节,因此甚至无法跟踪这些字节。)
malloc
通常使用内存池,“元数据”保存在池中,而不是在分配的内存块之间。
malloc
通常使用内存池,“元数据”保存在池中,而不是在分配的内存块之间。

而不是从已编译的固定大小数组中进行分配,malloc将根据需要从操作系统请求空间。由于程序中的其他活动也可以在不调用此分配器的情况下请求空间,因此malloc管理的空间可能不连续。因此,它的空闲存储被保存为空闲块列表。每个块都包含一个大小、指向下一个块的指针以及空间本身。这些块按存储地址递增的顺序保存,最后一个块(最高地址)指向第一个


当发出请求时,将扫描空闲列表,直到找到足够大的块。此算法称为
first-fit
,与
best-fit
相反,best-fit查找满足请求的最小块。如果块正好是请求的大小,它将从列表中取消链接并返回给用户。如果块太大,则会将其拆分,并将适当的数量返回给用户,而剩余部分仍保留在空闲列表中。如果没有找到足够大的块,操作系统将获得另一个大块并链接到空闲列表中

malloc将根据需要从操作系统请求空间,而不是从已编译的固定大小数组中进行分配。由于程序中的其他活动也可以在不调用此分配器的情况下请求空间,因此malloc管理的空间可能不连续。因此,它的空闲存储被保存为空闲块列表。每个块都包含一个大小、指向下一个块的指针以及空间本身。这些块按存储地址递增的顺序保存,最后一个块(最高地址)指向第一个

当发出请求时,将扫描空闲列表,直到找到足够大的块。此算法称为
first-fit
,与
best-fit
相反,best-fit查找满足请求的最小块。如果块正好是请求的大小,它将从列表中取消链接并返回给用户。如果块太大,则会将其拆分,并将适当的数量返回给用户,而剩余部分仍保留在空闲列表中。如果没有找到足够大的块,操作系统将获得另一个大块并链接到空闲列表中

仅供参考:。函数malloc()可用于双链接列表以及其他一些开销。因此,连续的malloc调用不会返回彼此之间预期偏移量的地址。此外,char在函数调用中被提升为int。此外,malloc()的大多数实现都以最小大小的倍数使用内存,以减少必要的数学计算量。此外,许多malloc()实现使用预先分配的内存池。结果