Chapter Six Question One

Linux Programming Interface Michael Kerrisk

Compile the program in Example 6-1 (see this program), and list its size using ls -l. Although the program contains an array (mbuf) that is around 10 MB in size, the executable file is much smaller than this. Why is this?

Implementation


/**
 * Chapter Six Question One
 *
 * Compile the program in Example 6-1 (see this program), and list its size using ls -l.
 * Although the program contains an array (mbuf) that is around 10 MB in size, the executable
 * file is much smaller than this. Why is this?
 *
 * The bss or uninitialized section is large, see below:
 *
 * mike@phobos:~/CLionProjects/chapterSixQuestionOne/cmake-build-debug$ ls -al
 * -rwxr-xr-x 1 mike mike 11720 Jul  3 23:54 chapterSixQuestionOne
 *
 * mike@phobos:~/CLionProjects/chapterSixQuestionOne/cmake-build-debug$ size chapterSixQuestionOne
 * text    data     bss     dec     hex filename
 * 1918     636 10305568        10308122         9d4a1a chapterSixQuestionOne
 *
 * The uninitialized data segment contains global and static variables that are not explicitly initialized.
 * Before starting the program, the system initializes all memory in this segment to 0. For historical reasons,
 * this is often called the bss segment, a name derived from an old assembler mnemonic for “block started by symbol.”
 * The main reason for placing global and static variables that are initialized into a separate segment from those
 * that are uninitialized is that, when a program is stored on disk, it is not necessary to allocate space for the
 * uninitialized data. Instead, the executable merely needs to record the location and size required for the
 * uninitialized data segment, and this space is allocated by the program loader at run time.
 */
#include <stdio.h>
#include <stdlib.h>

char globBuf[65536];            /* Uninitialized data segment */
int primes[] = { 2, 3, 5, 7 };  /* Initialized data segment */

static int square(int x)                   /* Allocated in frame for square() */
{
    int result;                 /* Allocated in frame for square() */

    result = x * x;
    return result;              /* Return value passed via register */
}

static void doCalc(int val)                 /* Allocated in frame for doCalc() */
{
    printf("The square of %d is %d\n", val, square(val));

    if (val < 1000) {
        int t;                  /* Allocated in frame for doCalc() */

        t = val * val * val;
        printf("The cube of %d is %d\n", val, t);
    }
}

int main(int argc, char *argv[])    /* Allocated in frame for main() */
{
    static int key = 9973;      /* Initialized data segment */
    static char mbuf[10240000]; /* Uninitialized data segment */
    char *p;                    /* Allocated in frame for main() */

    p = malloc(1024);           /* Points to memory in heap segment */

    doCalc(key);

    exit(EXIT_SUCCESS);
}