当使用相同的代码时,只需更改编译器(从C编译器更改为C++编译器)就会更改分配的内存量.我不太确定为什么会这样,我想更多地了解它.到目前为止,我得到的最好的回应是"可能是I/O流",这不是很有描述性,这让我对C++的"不用的东西不用付费"这一方面感到疑惑.

我使用的是Clang和GCC编译器,分别是7.0.1-8和8.3.0-6版本.我的系统运行在Debian 10(Buster)上,这是最新版本.基准测试通过Valgrind Massif完成.

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

使用的代码不会更改,但无论我编译为C还是C++,它都会更改Valgrind基准测试的结果.但是,这些值在编译器之间保持一致.程序的运行时分配(峰值)如下:

  • GCC(C):1032字节(1KB)
  • G++(C++):73744字节(~74KB)
  • Clang(C):1032字节(1KB)
  • Clang++(C++):73744字节(~74KB)

对于编译,我使用以下命令:

clang -O3 -o c-clang ./main.c
gcc -O3 -o c-gcc ./main.c
clang++ -O3 -o cpp-clang ./main.cpp
g++ -O3 -o cpp-gcc ./main.cpp

对于Valgrind,我在每个编译器和语言上运行valgrind --tool=massif --massif-out-file=m_compiler_lang ./compiler-lang次,然后运行ms_print次以显示峰值.

我做错什么了吗?

推荐答案

堆使用来自C++标准库.它为启动时的内部库使用分配内存.如果你不链接它,C和C++版本之间应该是零差值.使用GCC和Clang,您可以使用以下工具编译文件:

g++ -Wl,--as-needed main.cpp

这将指示链接器不要链接未使用的库.在示例代码中,不使用C++库,因此它不应该链接到C++标准库.

您还可以使用C文件测试这一点.如果使用以下命令进行编译:

gcc main.c -lstdc++

堆使用情况将再次出现,即使您已经构建了一个C程序.

堆使用显然取决于您正在使用的特定C++库实现.在你的例子中,这是GNU C++库,libstdc++.其他实现可能不会分配相同数量的内存,或者根本不会分配任何内存(至少在启动时不会)LLVM C++库(libc++)在启动时不做堆分配,至少在我的Linux机器上是这样的:

clang++ -stdlib=libc++ main.cpp

堆的使用与根本不针对它进行链接是一样的.

(如果编译失败,则可能没有安装libc++.包名通常包含"libc++"或"libcxx".)

C++相关问答推荐

在struct中调用函数,但struct在void中 *

如何在IF语句中正确使用0.0

fwrite无法写入满(非常大)缓冲区

如何在C中使printf不刷新标准输出?

CSAPP微型shell 实验室:卡在sigprocmask

加密解密工作正常,但返回错误0x80090005

如何有效地编写代码来判断两个元素数量相同的数组即使在不同的位置也具有相同的元素?

为什么未初始化的 struct 的数组从另一个数组获取值?

在C中包装两个数组?

我应该在递归中使用全局变量吗

运行时错误:在索引数组时加载类型为';char';`的空指针

为什么编译器不能简单地将数据从EDI转移到EAX?

如何对现有的双向循环链表进行排序?

是否有单独的缓冲区用于读写库调用?

我编写这段代码是为了判断一个数字是质数、阿姆斯特朗还是完全数,但由于某种原因,当我使用大数时,它不会打印出来

UpDown控制与预期相反

将char*铸造为空**

clion.我无法理解 Clion 中发生的 scanf 错误

运行以下 C 程序时出现分段错误

在 C 上使用函数的数组