Consider this empty program:
int main()
{ return 0; }
If I compile it with C++ with g++ main.cpp && strace ./a.out
, and analyze the output with strace
, I observed that the last lines of the output are (you can add -O3
that the effect is the same):
mprotect(0x7f71af154000, 45056, PROT_READ) = 0
mprotect(0x7f71af38b000, 4096, PROT_READ) = 0
brk(NULL) = 0xed2000
brk(0xf05000) = 0xf05000
exit_group(0) = ?
+++ exited with 0 +++
However, if I do instead: gcc main.cpp && strace ./a.out
mprotect(0x7f4114318000, 16384, PROT_READ) = 0
mprotect(0x7f4114547000, 4096, PROT_READ) = 0
exit_group(0) = ?
+++ exited with 0 +++
As you see, in C++ there's an extra brk
that extends the heap by exactly 204KB (0xf05000 - 0xed2000 = 204KB after translating both to decimal). That can be easily verified by replacing that program by (coliru link):
#include <iostream>
#include <unistd.h>
int main()
{
char buf[1024];
sprintf(buf, "pmap -XX %u", getpid());
std::system(buf);
return 0;
}
and you can easily observe that compiling with g++
the [heap]
has a size of 204KB, and with gcc
the [heap]
line even disappeared from the pmap
output.
NOTE: By the way, and to my surprise, gcc had no problem at all with include <iostream>
and with the presence of std
in std::system
.
What are these 204KB used for? Not worried or anything about these little 204KB but it caught my attention and I'm curious now.
This is due to the emergency buffer allocated by the C++ language runtime. When an exception is thrown, the runtime makes a copy of the thrown object in dynamically allocated memory. If it is unable to dynamically allocate enough memory, the GCC implementation falls back to allocating space from an emergency buffer it allocates at program startup. If that fails, it calls std::terminate()
.
This behaviour is implementation-defined. You will find other C++ language runtime implementations may do things differently.