Thread: Memory allocation at compile time

  1. #1
    Registered User
    Join Date
    Oct 2022
    Posts
    92

    Memory allocation at compile time

    Hello,

    I've been studying memory allocation for variables in C programs, but I'm still not entirely clear on the process. My understanding is that memory for variables isn't allocated until the program runs on a PC. During compilation, the source code is translated into machine code, which includes instructions for memory allocation and program logic. This seems to imply that memory allocation happens at runtime. However, I'm confused about how memory allocation can occur at compile time when the program doesn't actually run on hardware during compilation.

    Could you please clarify this concept of memory allocation in C programs?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Consider this example
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    int data[10] = { 0,1,2,3,4,5,6,7,8,9 };
    char large[1000];
    int main ( ) {
        void *p = malloc(100);
        printf("%d %d\n", data[0], large[0]);
        free(p);
    }
    
    $ gcc foo.c
    $ size a.out 
       text	   data	    bss	    dec	    hex	filename
       1600	    672	   1032	   3304	    ce8	a.out
    When the OS is told to load and run the program, it examines this information about your program.
    text is where your program code resides. 1600 bytes(*) is allocated by the OS and initialised with the program code from the file. In most OS's, this is made read-only/executable after initialisation.
    data is where initialised data (such as the array called data) resides. This too is copied from the file.
    bss is also for data, but for anything which is default initialised to all zeros (such as the array called large). Only the size is stored in the file, as it's pointless to read a whole bunch of zeros when all the OS has to do is memset.

    Behind the scenes, you also get a stack and a heap for runtime use (calling functions, allocating memory).

    So at the point your main starts executing, the OS has allocated and initialised memory for your program code, your global data, given you a stack and created a heap for future dynamic memory allocations.

    This you immediately make use of by calling malloc.


    (*) sizes are typically rounded up to some multiple of the page size.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2022
    Posts
    92
    Quote Originally Posted by Salem View Post
    Consider this example
    I've been reviewing your code, but I'm not getting a clear idea of how memory allocation works in this context. Specifically, I'm interested in understanding the distinction between memory allocation at compile time and run time.

    I'm curious about what happens when we compile code but don't actually run the program on hardware. Does memory get allocated for any variables defined in the code during the compilation process, even if the program isn't executed?

    Code:
     #include <stdio.h>
    #include <stdlib.h>
    
    // Global variable
    int globalVar = 10;
    
    
    // Static global variable
    static int staticGlobalVar = 20;
    
    
    int main() {
        // Local variable
        int localVar = 5;
    
    
        // Static local variable
        static int staticLocalVar = 15;
    
    
        // Dynamic memory allocation using pointers
        int *dynamicVar = (int *)malloc(sizeof(int));
    
    
        if (dynamicVar == NULL) {
            printf("Memory allocation failed.\n");
            return 1;
        }
    
    
        *dynamicVar = 25;
    
    
        // Extern variable (defined in another source file)
        extern int externVar;
    
    
        // Pointer variable
        int *pointerVar;
        pointerVar = &globalVar;
    
    
        printf("Global variable: %d\n", globalVar);
        printf("Static global variable: %d\n", staticGlobalVar);
        printf("Local variable: %d\n", localVar);
        printf("Static local variable: %d\n", staticLocalVar);
        printf("Dynamic variable: %d\n", *dynamicVar);
        printf("Extern variable: %d\n", externVar);
        printf("Pointer variable (points to globalVar): %d\n", *pointerVar);
    
    
        // Free dynamically allocated memory
        free(dynamicVar);
    
    
        return 0;
    }
    Memory layout categories:

    Program Memory: Stores instruction code.
    Data Memory: Holds variables and data.
    Stack Memory: function calls and local variables.
    Heap Memory: Used for dynamic memory allocation.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    No memory at all gets allocated at compile time.

    Memory is only allocated when the program is actually run.

    What happens at compile time though is the compiler saying
    "I want x bytes of memory reserved for a variable named globalVar"
    "I want y bytes of memory reserved for a function called main"
    etc
    etc

    In essence, it's more like "memory is reserved" by the compiler.

    Look at the assembler generated by your code.
    Code:
    $ gcc -S foo.c
    $ head -50 foo.s
    	.file	"foo.c"
    	.text
    	.globl	globalVar
    	.data
    	.align 4
    	.type	globalVar, @object
    	.size	globalVar, 4
    globalVar:
    	.long	10
    	.align 4
     	.type	staticGlobalVar, @object
    	.size	staticGlobalVar, 4
    staticGlobalVar:
    	.long	20
    	.section	.rodata
    .LC0:
    	.string	"Memory allocation failed."
    .LC1:
    	.string	"Global variable: %d\n"
    .LC2:
    	.string	"Static global variable: %d\n"
    .LC3:
    	.string	"Local variable: %d\n"
    .LC4:
    	.string	"Static local variable: %d\n"
    .LC5:
    	.string	"Dynamic variable: %d\n"
    .LC6:
    	.string	"Extern variable: %d\n"
    	.align 8
    .LC7:
    	.string	"Pointer variable (points to globalVar): %d\n"
    	.text
    	.globl	main
    	.type	main, @function
    main:
    .LFB6:
    	.cfi_startproc
    	endbr64
    	pushq	%rbp
    	.cfi_def_cfa_offset 16
    	.cfi_offset 6, -16
    	movq	%rsp, %rbp
    	.cfi_def_cfa_register 6
    	subq	$32, %rsp
    	movl	$5, -20(%rbp)
    	movl	$4, %edi
    	call	malloc@PLT
    // snipped
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Oct 2022
    Posts
    92
    Quote Originally Posted by Salem View Post
    No memory at all gets allocated at compile time.

    Memory is only allocated when the program is actually run.
    below statment confused me from link Difference between Static and Dynamic Memory Allocation in C - GeeksforGeeks

    it say memory allocation can also done before execution of program

    Memory Allocation: Memory allocation is a process by which computer programs and services are assigned with physical or virtual memory space. The memory allocation is done either before or at the time of program execution

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > it say memory allocation can also done before execution of program
    If you're running on a machine without an OS, then that's likely true.

    But allocation is perhaps the wrong word here.

    It would perhaps be better to say each object (with global scope) is assigned a memory location, which in principle, you can decide where that is.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Oct 2022
    Posts
    92
    Quote Originally Posted by Salem View Post
    > it say memory allocation can also done before execution of program
    If you're running on a machine without an OS, then that's likely true.

    But allocation is perhaps the wrong word here.

    It would perhaps be better to say each object (with global scope) is assigned a memory location, which in principle, you can decide where that is.
    I've noticed that many sources mention that dynamic memory allocation occurs at runtime, but I'm struggling to see a clear distinction between dynamic memory allocation and memory allocation for other types of variables like global, local, or static variables. It seems that memory allocation, in general, happens when the program is running. The difference could be that the compiler generates different instructions for handling these different types of variables. Could you confirm if my understanding is correct in this regard?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Certainly, dynamic allocation is memory you get at runtime through some action of your program deciding that it needs to allocate some memory.

    As for the rest, well it depends on your point of view.

    Memory for say a global variable needs a memory location defined at some point.

    If you're writing bare metal code where your code is burned into a ROM, the location is decided before you even switch on the machine. It's fixed in the ROM.

    But if your program is loaded by an OS of some sort, the program file indicates how much memory it needs to begin with, and the OS allocates that memory for use by your program.
    By the time code execution hits your main(), the OS will have done all the initial work for you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Kittu20:

    Global variables, static variables, and local variables are defined in the code when the code is compiled.

    Memory for globals and static variables are actually allocated when the program is loaded into memory when the program is executed.

    Memory for Local variables are allocated in the stack frame when the function is called.

    Dynamic memory allocation is done with the functions, malloc(), and calloc(). The "heap" is an area of memory that is allocated when the program is executed, but the memory is not in use until malloc() or calloc() is called.

    Calls to either function, allocates a portion of the heap, and assigns to a pointer. That memory can then be used by the program through the pointer, until the address returned by either function is passed to free() to free up the memory, and then is available for a subsequent allocation later in the program.

    Please see the manpage for malloc() and related functions.

    To fully understand this and all the other details of the C Programming Language, can be learned through studying a good up-to-date book on the language.


    If you are attempting to learn from painfully inadequate online tutorials, YouTube videos, or some book claiming to teach you in a short time, then THROW THEM AWAY!

    Short of taking a course in C Programming from a qualified instructor, you need to study a good book on the C Programming Language, cover to cover, and do all the exercises at the end of each chapter! Choose one of the three listed below:

    C Programming, A Modern Approach, 2nd Edition
    Author: K. N. King

    C Primer Plus, 6th Edition
    Stephen Prata

    C How to Program, 8/e
    Deitel & Deitel

    Studying one of these books, doing the exercises, and writing code, you will have a much better understanding of the C Programming language.
    Last edited by rstanley; 09-30-2023 at 11:55 AM.

  10. #10
    Registered User
    Join Date
    Oct 2022
    Posts
    92
    In the context of an operating system, if memory is allocated at runtime when a program executes, what exactly is the role of the linker? I see that the linker combines all object files into one executable file, but how does it know if a variable is defined in another source file? And how does it identify when memory allocation occurs at runtime because linker process occur before run time?

  11. #11
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    When you have multiple .c source files, you would have a .h header file. In that .h file you would have a declaration of the global variable:
    Code:
    extern int var;
    You would define the variable in one and only one .c file, and use the variable in the other .c file. You would #include the header file in all the .c files that need to define or use the global variable.

    The linker would resolve all references to the declaration, definition, and use of the variable during the compile process, to the defined variable.

    You really need to study the language before attempting to program using the language. You would learn all these details in one of the boos I have recommended..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory allocation at run time
    By skyr6546 in forum C Programming
    Replies: 1
    Last Post: 12-16-2021, 05:55 AM
  2. Can you get memory addresses from compile time
    By bassileian.rob in forum C Programming
    Replies: 2
    Last Post: 09-01-2013, 09:37 AM
  3. Replies: 2
    Last Post: 01-12-2013, 10:11 AM
  4. Help! -Linked Lists, Memory Allocation, Time Steps, Debugg
    By MetallicaX in forum C Programming
    Replies: 2
    Last Post: 03-14-2009, 08:50 PM
  5. Memory allocation error (Nicely formatted this time)
    By killiansman in forum C Programming
    Replies: 1
    Last Post: 06-08-2007, 11:14 AM

Tags for this Thread