Memory management in c

Thread Starter

Kittu20

Joined Oct 12, 2022
473
Hey everyone,

I've been diving deeper into the world of C programming, and I came across a topic that I'm hoping you can help me clarify. I want to understand when memory locations for variables are actually assigned in C - is it at runtime, compile time, or link time?

I've read a bit about it, but I'm still a little confused, and I'm sure some of you more experienced programmers can shed some light on this. From what I gathered:

  1. Compile Time: During the compilation process, the C compiler translates the high-level C code into assembly language. However, I'm not sure if memory locations for variables are assigned at this stage or not.
  2. Link Time: After compilation, during the linking phase, object files are combined to create an executable or a shared library. Again, I'm not entirely sure if memory allocation happens here.
  3. Runtime: This is the phase where the program is actually executed. I've heard that memory locations for variables are assigned during runtime. But how exactly does this work? Does the compiler have any role in this process?

Could someone clarify these points for me?

Looking forward to learning from you all!

Thanks! @WBahn
 
Last edited:

WBahn

Joined Mar 31, 2012
30,063
What do you mean by "allocated". A program that isn't running doesn't have any memory allocated for it's variables -- it's just a file with a bunch of ones and zeroes sitting on a disk somewhere. So, in that sense, all memory is allocated at runtime.

The C language specification doesn't define how things are done, merely what the required behavior is. The compiler developer has a lot of flexibility in how to achieve that behavior, so it's impossible to say for sure how it is done, since it can vary quite a bit form one compiler to the next, but there are some common approaches that are used.

How memory allocation is handled depends on what storage class the variable belongs to: auto, extern, static, or register. Notice that dynamically allocated memory is not included -- that's a different issue altogether.

Most "normal" variables you use are of automatic storage class. They are allocated on the stack when a block starts and deallocated when the block exits.

Static variables are allocated space when the program starts that remains fixed throughout the life of the program. Exactly where that space is located depends on the compiler. A common layout, at least conceptually, is the following:

Taken from: https://www.geeksforgeeks.org/memory-layout-of-c-program/

1690391626370.png

When a program is loaded into memory, it is assigned a block of memory (from low address to high address). The OS places command line arguments and environment variables at the high end of the block and loads the code into the low end of the block. The code contains not only the actual program instructions (the 'text'), but also the contents of static memory that is initialized. So, in that sense, those variables are allocated memory at link time because they are literally part of the executable file. Static variables that are not initialized are assigned locations in the bss area directly after the end of the program file space. This area is initialized to all zero by the OS when it loads the program. The stack and heap have the remaining memory and start at opposite ends and grow toward each other in order to maximize the amount of memory that can be utilized before bad things happen.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
473
A program that isn't running doesn't have any memory allocated for it's variables -- it's just a file with a bunch of ones and zeroes sitting on a disk somewhere. So, in that sense, all memory is allocated at runtime.
So, memory locations are assigned at runtime when the program is executed on the microcontroller,

When a program is loaded into memory, it is assigned a block of memory (from low address to high address).
While reading about this topic, I came across some intriguing information that I'd like to discuss and clarify with all of you.

From what I understand, the memory locations for variables are not actually assigned at compile time, as I previously believed. Instead, it happens at runtime when the program is loaded into memory. However, I'm still unsure about the finer details of how microcontroller handle this memory allocation process.

How the microcontroller assigns memory locations for variables at runtime?

The stack and heap have the remaining memory and start at opposite ends and grow toward each other in order to maximize the amount of memory that can be utilized before bad things happen.
The stack and heap are two separate regions of memory used for different purposes.

  • Stack: The stack is used for storing function call information, local variables, and function call parameters. It grows and shrinks automatically as functions are called and return.
  • Heap: The heap is used for dynamic memory allocation, such as when we use malloc()
 

WBahn

Joined Mar 31, 2012
30,063
If you are talking about running a C program on a microcontroller, you are likely talking about a freestanding implementation, as opposed to a hosted implementation such as would be the case running of a PC with an operating system. The details of things like this depend somewhat on which type of implementation is being discussed.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
473
If you are talking about running a C program on a microcontroller, you are likely talking about a freestanding implementation, as opposed to a hosted implementation such as would be the case running of a PC with an operating system. The details of things like this depend somewhat on which type of implementation is being discussed.
So, compiler generates the necessary instructions for memory allocation at run time but the actual allocation occurs when the program is run on target machine
 

MrChips

Joined Oct 2, 2009
30,814
No. It depends on the system you are running.

Are you talking about an MCU embedded system or a full blown Windows PC?

On a bare bones MCU system, ASM code or C code can specify the physical memory locations even before the code gets compiled.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
473
On a bare bones MCU system, ASM code or C code can specify the physical memory locations even before the code gets compiled.
In embedded systems or MCU programming, how does manual memory allocation work, Can you explain in more detail how ASM code or C code can specify physical memory locations in a bare bones MCU system?

EDIT : ARM , Keil, C
 

WBahn

Joined Mar 31, 2012
30,063
In embedded systems or MCU programming, how does manual memory allocation work, Can you explain in more detail how ASM code or C code can specify physical memory locations in a bare bones MCU system?
In assembly language, especially on an MCU, you usually have complete control over everything. If you want the variable Fred to be stored at memory address 42, then you can use memory address 42 to store the variable Fred.

I've suggested this before, and you've completely ignored it, but if you want to start getting a good handle on a lot of these concepts, work your way through the Nand2Tetris project.
 

MrChips

Joined Oct 2, 2009
30,814
On every MCU, memory begins at a fixed physical location, for example at $0000.

When you begin declaring a variable, it makes sense to assign addresses from that starting point.

In ASM, one can specify where you want the variables to be located.
For example, you can write something such as,

.EQU myvariable 0x0200
 

lisahall

Joined Jan 22, 2024
2
In C programming, memory locations for variables are assigned during runtime. Unlike some other languages where memory allocation may happen at compile or link time, C follows a runtime approach. During the execution of the program, the operating system allocates memory for variables as needed. The compiler plays a role in generating code that specifies the variables and their types, but the actual assignment of memory locations occurs dynamically during the program's runtime. This runtime allocation provides flexibility but requires careful management to avoid memory-related issues.
 

Papabravo

Joined Feb 24, 2006
21,225
In C programming, memory locations for variables are assigned during runtime. Unlike some other languages where memory allocation may happen at compile or link time, C follows a runtime approach. During the execution of the program, the operating system allocates memory for variables as needed. The compiler plays a role in generating code that specifies the variables and their types, but the actual assignment of memory locations occurs dynamically during the program's runtime. This runtime allocation provides flexibility but requires careful management to avoid memory-related issues.
This is manifestly not the case for an embedded system. They usually run without an OS that would provide such a service.
 
Top