在 C++ 中不执行任何操作的空程序需要 204KB 的堆,但在 C 中不需要

问题描述 投票:0回答:1

考虑这个空程序:

int main()
{ return 0; }

如果我用C++用

g++ main.cpp && strace ./a.out
编译它,并用
strace
分析输出,我观察到输出的最后几行是(你可以添加
-O3
,效果是一样的):

mprotect(0x7f71af154000, 45056, PROT_READ) = 0
mprotect(0x7f71af38b000, 4096, PROT_READ) = 0
brk(NULL)                               = 0xed2000
brk(0xf05000)                           = 0xf05000
exit_group(0)                           = ?
+++ exited with 0 +++

但是,如果我这样做:

gcc main.cpp && strace ./a.out

mprotect(0x7f4114318000, 16384, PROT_READ) = 0
mprotect(0x7f4114547000, 4096, PROT_READ) = 0
exit_group(0)                           = ?
+++ exited with 0 +++

如您所见,在 C++ 中,有一个额外的

brk
将堆精确扩展了 204KB(将两者转换为十进制后,0xf05000 - 0xed2000 = 204KB)。通过用(coliru链接)替换该程序可以轻松验证这一点:

#include <iostream>
#include <unistd.h>

int main()
{
    char buf[1024];
    sprintf(buf, "pmap -XX %u", getpid());
    std::system(buf);
    
    return 0;
}

并且您可以轻松观察到使用

g++
进行编译,
[heap]
的大小为 204KB,而使用
gcc
时,
[heap]
行甚至从
pmap
输出中消失了。

注意: 顺便说一句,令我惊讶的是,gcc 对于 include

<iostream>
以及
std
中存在
std::system
完全没有问题。

这204KB有什么用呢?不担心这些 204KB 的小东西,但它引起了我的注意,我现在很好奇。

c++ c gcc
1个回答
1
投票

删除

g++
添加的库,它不会进行额外的分配:
g++ -nodefaultlibs -lc main.cpp

使用默认库,C++ 程序会链接到:

        /lib64/ld-linux-x86-64.so.2
        libc.so.6 => /lib64/libc.so.6
        libgcc_s.so.1 => /lib64/libgcc_s.so.1
        libm.so.6 => /lib64/libm.so.6
        libstdc++.so.6 => /lib64/libstdc++.so.6
        linux-vdso.so.1

没有默认库 +

libc
:

        /lib64/ld-linux-x86-64.so.2
        libc.so.6 => /lib64/libc.so.6
        linux-vdso.so.1

额外的库是:

        libgcc_s.so.1 => /lib64/libgcc_s.so.1
        libm.so.6 => /lib64/libm.so.6
        libstdc++.so.6 => /lib64/libstdc++.so.6

无论如何,我想知道哪个特定的 C++ 库增加了堆

通过一次将一个额外的库添加到链接库中,我们可以看到,正是

libstdc++
导致了额外的分配,因此,如果您可以在没有 C++ 标准库的已编译部分的情况下逃脱,这就是您所要做的可以使用:

g++ -nodefaultlibs -lgcc_s -lm -lc
© www.soinside.com 2019 - 2024. All rights reserved.