当前位置: 首页 > 知识库问答 >
问题:

马洛克

公子昂
2023-03-14

所以,我有这段代码:

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

>

如果我们使用calloc,程序会分配大约2 GB的内存,然后停止(此处照片=

(奇怪的测试):如果我们同时使用这两者,它将使用最大值(~400MB~2GB)/2=

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

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

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

编辑:

>

  • de::BGNU GCC编译器锁定13.12

    Windows 10(x64)

    Linux Mint 17.2“Rafaela”-肉桂色(64位)(用于Linux测试)

  • 共有1个答案

    松洛华
    2023-03-14

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

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

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

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

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

     类似资料:
    • 本文向大家介绍病毒,蠕虫和特洛伊木马之间的区别,包括了病毒,蠕虫和特洛伊木马之间的区别的使用技巧和注意事项,需要的朋友参考一下 众所周知,这三类都是不需要的计算机程序/代码,它们会导致运行缓慢或完全停止执行程序,这是由于系统本质上表现异常。 根据这些程序/代码的功能和类型,我们可以区分病毒,蠕虫和特洛伊木马,如下所示: 序号 键 病毒 虫 特洛伊木马 1 定义 病毒可以定义为计算机程序或软件,它们

    • 基于openresty的web防火墙,通过配合后台保护您的数据安全 项目说明 由于普通的web防火墙通常只是单台的限制, 并不能对集群中的流量进行全局的分析 从而无法达到有效的防止cc的攻击, 攻击者可分散攻击而让单台无法分析出其是否是恶意的攻击 所以需要有中台的分析,才能有效的判断是否为恶意IP,从而可以自动的识别出哪些用户是非法IP, 从而实行自动封禁, 基本上能保证90%以上的CC攻击自动拦

    • 我已经搜索了一段时间,但没有找到这个问题的合适答案。我注意到我的防病毒软件开始检测到我的应用程序是特洛伊木马。我的防病毒软件是卡巴斯基2013,这是它检测到的特洛伊木马类型。http://www.securelist.com/en/descriptions/HEUR:Trojan.Win32.Generic 我的应用程序只做3件事: > 使用加密狗密钥解密dll(即具有自定义入口点的wpf类库)

    • 主要内容:弗洛伊德算法的实现思路,弗洛伊德算法的具体实现在一个加权图中,如果想找到各个顶点之间的最短路径,可以考虑使用弗洛伊德算法。 弗洛伊德算法既适用于无向加权图,也适用于有向加权图。使用弗洛伊德算法查找最短路径时,只允许环路的权值为负数,其它路径的权值必须为非负数,否则算法执行过程会出错。 弗洛伊德算法的实现思路 弗洛伊德算法是基于 动态规划算法实现的,接下来我们以在图 1 所示的有向加权图中查找各个顶点之间的最短路径为例,讲解弗洛伊德算法的实现思

    • 我的服务器机器上运行单节点kafka。我使用以下命令创建主题“bin/kafka-topics.sh--创建--zookeeper本地主机:2181--复制因子1--分区1--主题测试”。我有两个logstash实例正在运行。第一个从一些java应用程序日志文件中读取数据,并将其注入kafka。它工作得很好,我可以使用“bin/kafka-console-consumer.sh——zookeepe