c - 分配和分配 : different memory size allocated

标签 c memory memory-management malloc calloc

所以,我有这段代码:

#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 上运行。有趣的事情:

  • 如果我们使用 malloc,程序会分配大约 430 MB 的内存然后停止(照片在这里 => http://i.imgur.com/woswThG.png)

  • 如果我们使用 calloc,程序会分配大约 2 GB 的内存然后停止(照片在这里 => http://i.imgur.com/3JKy5pA.png)

  • (奇怪的测试):如果我们同时使用它们,它最多使用 (~400MB + ~2GB)/2 => ~1.2GB

但是,如果我在 Linux 上运行相同的代码,分配会一直持续(在分配了 600k 并使用了许多 GB 之后,它仍然会继续,直到最终被终止)并且使用的内存量大致相同。

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

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

编辑:

  • Code::Blocks 13.12 与 GNU GCC 编译器

  • Windows 10 (x64)

  • Linux Mint 17.2“Rafaela”- Cinnamon(64 位)(用于 Linux 测试)

最佳答案

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

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

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

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

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

关于c - 分配和分配 : different memory size allocated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34023336/

相关文章:

c - 不包括 stdlib.h 不会产生任何编译器错误!

java - 内存不足错误: Java heap space when trying to create ArrayList

ios - UIButton 从内存中释放?

c - Printf 和 scanf 无法正常工作? C语言编程

c - 从 EOL 中删除字符

ios - 如何使用大型 csv 文件管理 ios 的内存?

c++ - 引用表溢出(最大值=1024)

c++ - 如果没有堆内存,如何释放 std::vector

c - 当全局变量和局部变量同名时访问全局变量

c++ - IsBadReadPtr 的最有效替代品?