C分配和内存开销

Mig*_*ork 1 c memory memory-management

如果这是一个愚蠢的问题,请道歉,但很长一段时间以来一直困扰着我.

我想知道内存管理器如何知道正在使用的内存的一些细节.

想象一下拥有1024B RAM的单片机 - 没什么好处的.

现在你分配100个整数 - 每个int是4个字节,每个指针也是4个字节(是的,8位单片机很可能有更小的指针,但是w/e).

所以你刚刚使用800B的内存100英镑?但更糟糕的是 - 分配系统必须以某种方式记录内存的mallocd以及它在哪里 - 200个额外的字节或其他东西?还是有点痕迹?


  • 如果这是真的,为什么C经常偏爱汇编程序呢?

  • 这真的是这样吗?超级效率低吗?

  • (或者我对它有一个完全不正确的想法?)

Ric*_*ges 9

可能会让年轻的开发人员感到惊讶,因为像我这样老的老用户曾经用1或2k RAM的系统用C语言编写.

在这种规模的系统中,动态内存分配将是我们无法承受的奢侈品.它不仅仅是管理免费存储的指针开销,还有免费存储碎片的影响,使内存分配效率低下,很可能导致致命的内存不足(虚拟内存不是一种选择).

因此我们习惯使用静态内存分配(即全局变量),对所有嵌套的函数深度进行非常严格的控制,并对嵌套中断处理进行更严格的控制.

在这些系统上书写时,我甚至没有链接标准库.我编写了自己的C启动例程并提供了自定义的最小I/O例程.

我在2k ram系统中编写的一个程序使用RAM的下半部分作为数据区域,上部部分作为堆栈.在最后的剪辑中,我证明了堆栈的最大使用量在内存中达到了目前为止距离数据区域中的最后一个变量1个字节.

啊,过去的美好时光......

编辑:

要具体回答您的问题,原来的K&R免费商店经理用于将标题块添加到通过分配的每个内存块的开头malloc.

标题块看起来像这样:

union header {
    struct {
    union header   *ptr;
    unsigned        size;
    } s;
};
Run Code Online (Sandbox Code Playgroud)

ptr下一个标题块的地址在哪里,大小是分配的内存大小(以块为单位).该malloc函数实际上将返回由...计算的地址&header + sizeof(header).自由函数将从您提供的指针中减去标题的大小,以便将块重新链接回空闲列表.