书中记忆分配的练习名为"专家C编程"

时间:2014-06-05 04:48:22

标签: c memory-management

练习要求我看看如果在后面的程序中分配的内存块小于1MB会发生什么:

#include <stdio.h>
#include <stdlib.h>
main()
{
    int MB=0;
    while(malloc(1<<20))
        ++MB;
    printf("Allocated %d MB total\n",MB);
}

我的笔记本电脑上的结果是

  

分配总计3056 MB

比我改变这样的程序:

#include <stdio.h>
#include <stdlib.h>
main()
{
    int MB=0;
    while(malloc(1<<19))
        ++MB;
    printf("Allocated %d MB total\n",MB/2+MB%2);
}

结果是

  

分配总计3045 MB

我的程序改变了吗? 为什么结果小于3056MB?

2 个答案:

答案 0 :(得分:4)

  1. 是的,你的程序没问题。 (虽然总是将兆字节的数量四舍五入有点不合标准。)

  2. 当你致电free时,你不会告诉它你正在释放的块有多大。这意味着内存管理系统必须知道每个块有多大。这意味着它必须将信息存储在某个地方。由于它无法将信息存储在内存块中,因此必须将其存储在块外部,这通常意味着实际分配的内存比请求的内存略多。例如,它实际上可以分配比请求的块大size_t的块malloc,在开头存储块大小,然后告诉您块在之后。< / p>

  3. 大多数{{1}}实现会在页面边界上放置大量分配(通常页面为4K)。一种方法是使用仅针对单个size_t值的页面为每个分配浪费整个页面。这看起来很糟糕,但是如果你要求甚至半兆字节,一个页面的分配大小不到1%,浪费1%的总内存并不是那么糟糕。

    假设你的malloc做到了这一点。当您分配1MB块时,您设法分配3056块。如果每个分配比请求大4k页,则隐藏分配将为3056 * 4k,或略小于12兆字节。 (实际上它略低于12 mebibytes,但是当我指的是mebi时,我会继续说mega。)所以可用的总内存为3068 MB。

    当你改变它以分配½MB块时,你设法分配至少3045 * 2 - 1(假设MB的数量被四舍五入)。这是6089个额外页面,大约23.8 MB,加上3044.5 MB的分配,总计大约3068.3 MB。

    这些都没有证明你的malloc以这种方式工作,但它至少显示了一种可能的机制。

答案 1 :(得分:4)

1.每次运行此程序时,您都不会获得相同的结果。 因为你正在从堆中分配1MB内存块直到内存可用,并且特定时间的可用内存可能会有所不同。

2.您的代码没有错。

3.分配后你不会破坏内存,因此通常操作系统会释放在progrm存在后分配的内存。这是依赖于操作系统的,而嵌入式操作系统(RTOS)通常不会为你释放内存。