【问题标题】:malloc storing its metadatamalloc 存储其元数据
【发布时间】:2014-06-23 05:48:29
【问题描述】:

令人惊讶的是,即使数据类型不同,两个程序都给出了相同的两个指针之间的差异.....

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 调用将不会在彼此之间的预期偏移处返回地址。此外, char 在函数调用中被提升为 int 。此外,malloc() 的大多数实现都使用最小大小的倍数的内存来减少必要的数学计算量。此外,许多 malloc() 实现使用预分配的内存池。结果是几乎所有 malloc() 调用实际上获得的内存比预期的要多。

标签: c malloc


【解决方案1】:

malloc 将分配“四舍五入”为库编译时设置的方便大小。与创建分配以完全匹配请求的情况相比,这会导致后续分配和解除分配的内存碎片更少。

malloc 存储其元数据的位置实际上并不是为什么两者的值都是 0x20“分开”。但是您可以阅读实现malloc(和朋友)here 的一种方法;尤其是幻灯片 16 和 28。

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

【讨论】:

  • 你能详细说明你的答案吗..我想知道 malloc 究竟在哪里存储它的元数据的所有细节......??
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    malloc 通常使用内存池,并且“元数据”保存在池中,而不是分配的内存块“之间”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多