为什么 C 语言中的 malloc 函数分配的内存比机器配置多?

Why does the malloc function in C-language allocate more memory than the machine configuration?

提问人:czg 提问时间:4/25/2022 更新时间:4/25/2022 访问量:209

问:

我在 C 中使用 malloc 函数分配内存,但我遇到了一个奇怪的问题,我对此感到困惑。

以下是程序代码:

#include <stdio.h>
#include <stdlib.h>

#define _1M (1024 * 1024)

// TODO stackOverFlow question
int main(int c, char *v[]) {

    size_t max_allocatable_mem;
    long i = 1;
    char *addr = NULL;

    while (1) {

        max_allocatable_mem = _1M * i;
        addr = malloc(max_allocatable_mem);

        if (addr) {
            printf("allocatable % 16ld M\n", i++);
            free(addr);
        } else {
            printf("can not be allocated % 16ld M\n", i--);
            break;
        }

    }

    printf("\nmax_allocatable_mem = %ld M\n\n", i);

    size_t small_mem_block = max_allocatable_mem / 10;

    for (i=0; i<20; i++) {
        addr = malloc(small_mem_block);
        if (addr) {
            printf("starting address < %p >  capacity < %lu bytes >\n", addr, small_mem_block);
        } else {
            break;
        }
    }

    return 0;
}

程序最初使用 malloc 函数分配最大内存,然后记录可以分配的最大内存。然后,进行小内存的分配。每次分配的小内存是最大可分配内存的十分之一。连续分配 20 次,每次 malloc 都能返回一个特定的内存地址。这样,以后分配的小内存加起来就是程序最初可以分配的最大内存的两倍。

以下是在我的计算机上执行此代码的结果的输出:

allocatable             1332 M
allocatable             1333 M
allocatable             1334 M
allocatable             1335 M
allocatable             1336 M
can not be allocated             1337 M

max_allocatable_mem = 1336 M

starting address < 0x7f8787a4c010 >  capacity < 140194611 bytes >
starting address < 0x7f877f498010 >  capacity < 140194611 bytes >
starting address < 0x7f8776ee4010 >  capacity < 140194611 bytes >
starting address < 0x7f876e930010 >  capacity < 140194611 bytes >
starting address < 0x7f876637c010 >  capacity < 140194611 bytes >
starting address < 0x7f875ddc8010 >  capacity < 140194611 bytes >
starting address < 0x7f8755814010 >  capacity < 140194611 bytes >
starting address < 0x7f874d260010 >  capacity < 140194611 bytes >
starting address < 0x7f8744cac010 >  capacity < 140194611 bytes >
starting address < 0x7f873c6f8010 >  capacity < 140194611 bytes >
starting address < 0x7f8734144010 >  capacity < 140194611 bytes >
starting address < 0x7f872bb90010 >  capacity < 140194611 bytes >
starting address < 0x7f87235dc010 >  capacity < 140194611 bytes >
starting address < 0x7f871b028010 >  capacity < 140194611 bytes >
starting address < 0x7f8712a74010 >  capacity < 140194611 bytes >
starting address < 0x7f870a4c0010 >  capacity < 140194611 bytes >
starting address < 0x7f8701f0c010 >  capacity < 140194611 bytes >
starting address < 0x7f86f9958010 >  capacity < 140194611 bytes >
starting address < 0x7f86f13a4010 >  capacity < 140194611 bytes >
starting address < 0x7f86e8df0010 >  capacity < 140194611 bytes >

为什么连续分配多个小内存的容量加起来可以达到多个分配最大内存的容量? 会不会是掉期的影响?但是我的电脑上的 Swap 已关闭。

[root@ps-5 ~]# free
              total        used        free      shared  buff/cache   available
Mem:        1881820      434676      462456         632      984688     1288636
Swap:             0           0           0

我希望能得到帮助。

谢谢大家。

C 内存 malloc

评论

0赞 Some programmer dude 4/25/2022
请记住,分配的内存是连续的。分配较大的区块可能会失败,因为有足够的地址空间来容纳如此大的区块。但是对于较小的块,地址空间中可能有一些页面可以使用。malloc
4赞 Ingo Leonhardt 4/25/2022
这也可能是记忆过度使用的影响。如果将替换为malloc()calloc()
3赞 Gerhardh 4/25/2022
与您的问题无关,但是错误的。因为您应该使用格式说明符。< %lu bytes >size_t%zu
0赞 Guillaume Petitjean 4/25/2022
的行为取决于运行它的硬件和操作系统(如果有),甚至取决于 libC 版本。它在所谓的 .但是堆的管理是实现定义的。在微控制器和裸机代码上,一旦堆满了,它就满了。在Linux上,我认为操作系统可以通过调用函数来增加堆的大小。然后,虚拟内存的交换是另一个问题。mallocheapsbrk
0赞 Steve Summit 4/25/2022
现代操作系统上的内存分配很复杂!在 C 语言的上下文中,您不会找到问题的答案。我建议在你使用的操作系统(甚至可能是精确版本)的上下文中提出你的问题:Unix、Linux、MacOS、Windows 或其他任何操作系统。(也就是说,您可能希望选择特定于操作系统的 Stack Exchange 站点之一。

答: 暂无答案