Malloc & calloc:分配不同的内存大小

Malloc & calloc: different memory size allocated

所以,我有这段代码:

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

int main()
{
    char *p;
    long n = 1;

    while(1) {
        p = malloc(n * sizeof(char));
        //p = calloc(n, sizeof(char));

        if(p) {
            printf("[%ld] Memory allocation successful! Address: %p\n", n , p);
            n++;
         } else {
            printf("No more memory! Sorry...");
            break;
        }
    }

    free(p);
    getch();
    return 0;
}

我 运行 在 Windows 上。有趣的事:

但是,如果我 运行 在 Linux 上使用相同的代码,分配将继续进行(在 600k 分配和许多 GB 使用后它仍然继续直到最终被杀死)并且大约使用相同数量的内存。

所以我的问题是:他们不应该分配相同数量的内存吗?我认为唯一的区别是 calloc 用零初始化内存(malloc returns 未初始化的内存)。为什么它只发生在 Windows?既奇怪又有趣。

希望你能帮我解释一下。谢谢!

编辑:

查看程序输出,您实际上分配了相同数量的块,65188 用于 malloc65189 用于 calloc。忽略开销,这略小于 2GB 内存。

我的猜测是您在 32 位模式下编译(指针被转储为 32 位),这将单个用户进程可用的内存量限制在 2GB 以下。进程图显示的不同之处在于您的程序如何使用它分配的内存。

malloc版本不涉及分配的页面:其中超过四分之三的页面实际上没有映射,因此只有 430MB。

calloc 版本显示 2GB 的 mapped 内存:您的 C 库函数 calloc 可能会清除分配的内存,即使对于从OS。这不是最佳的,但只有在您不触摸分配的内存时才可见,无论如何都是一种特殊情况。然而,不清除从 OS 获得的页面会更快,因为它们被指定为零填充。

在 Linux 中,您可能正在编译为 64 位,可以访问超过 2GB 的虚拟进程 space。由于您没有触及内存,因此它没有被映射,在 calloc 情况下似乎也会发生同样的情况。 C 运行时不同(64 位 glibc 在 Linux 上,32 位 Microsoft 库在 Windows 上)。您应该在 Linux 的不同终端中使用 topps 来检查在这两种情况下实际映射到您的进程的内存量。