You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We'll start from the bottom, following the first image.
453
+
454
+
If you're trying to interpret the second image in terms of the first, just take it that literals and static data are stored in the `unitialised` and `initialised data` segments, depending on whether they are initialised or not. `int i;` vs `int i = 5;`
455
+
456
+
#### **Text Segment**
457
+
458
+
The text segment is where the actual executable code instructions are stored. It's placed below the heap and stack to prevent any overflows from either from overwriting it.
459
+
460
+
Pretty smart.
461
+
462
+
#### **Initialised Data/Data Segment**
463
+
464
+
This is where all the data that is initialised with non-zero data at compile time is stored.
465
+
466
+
- The **read-only** section of this segment will go to **literals**, like strings. Eg: `char s[] = "rawr"`
467
+
- The **read-write** section of this segment will go to static or global variables. Eg: `global int wow = 1;`
468
+
469
+
#### **Uninitialised Data/bss Segment**
470
+
471
+
(bss stands for "block started by symbol".)
472
+
473
+
All data here is initialised with 0. And it contains **all static or global data that is either explicitly initialised to 0 or does not have explicit initialisation in the source code.**
474
+
475
+
Some examples of stuff that's stored in the bss segment:
476
+
477
+
```c++
478
+
staticint a;
479
+
global int b;
480
+
481
+
// This one will NOT be in the bss! Since it's local to main, and will actually go to the stack.
482
+
intmain(){
483
+
int c = 0;
484
+
return 0;
485
+
}
486
+
```
487
+
488
+
#### **Stack and Heap**
489
+
490
+
The stack and heap actually share the same segment, and typically grow in opposite directions from opposite ends of the segment. Though some optimisations and compilers might break this guideline.
491
+
492
+

The stack follows last-in, first-out (LIFO) structure.
497
+
498
+
The top of the stack and heap are tracked using pointers. Once the two pointers meet, you've run out of memory. If you don't catch this, you'll get overflows, which will mean you're going to have a **bad time.**
499
+
500
+
Each time you call a function, a stack frame containing function variables, and information relating to the function caller's environments, return address, some machine registers, and other function-call related info are pushed to the stack. If you have a recursive function each recursive call actually generates a new stack frame on the stack.
501
+
502
+
> - The stack grows and shrinks as functions push and pop local variables
503
+
> - There is no need to manage the memory yourself, variables are allocated and freed automatically
504
+
> - The stack has size limits
505
+
> - Stack variables only exist while the function that created them, is running
The heap is where dynamic memory allocation typically happens.
513
+
514
+
You manage it by using `malloc`, `realloc`, `free` (C functions), or the newer `new`, `new[]`, `delete`, and `delete[]` C++ operators, which are better and almost always better to use.
515
+
516
+
Every thread, library, or module in a single program process has access to this data segment, since they're essentially global.
517
+
518
+
It's **normally slower to access heap data than stack data since you need to use pointers to access them.**
519
+
520
+
521
+
522
+
### 2.9 Heap and Stack <aname="2.9"></a>
523
+
524
+
[go to top](#top)
525
+
526
+
There's actually more to go through for the heap and stack, since they're the two data segments that you'll encounter most often.
527
+
528
+
> ## Stack vs Heap Pros and Cons
529
+
>
530
+
> ### Stack
531
+
>
532
+
> - Very fast access
533
+
> - Don't have to explicitly de-allocate variables
534
+
> - Space is managed efficiently by CPU, memory will not become fragmented
535
+
> - Local variables only
536
+
> - Limit on stack size (OS-dependent)
537
+
> - Variables cannot be resized
538
+
>
539
+
> ### Heap
540
+
>
541
+
> - Variables can be accessed globally
542
+
> - No limit on memory size
543
+
> - (Relatively) slower access
544
+
> - No guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed
545
+
> - You must manage memory (you're in charge of allocating and freeing variables)
546
+
> - Variables can be resized using `realloc()`
547
+
>
548
+
> ## When to use the Heap?
549
+
>
550
+
> When should you use the heap, and when should you use the stack?
551
+
>
552
+
> If you need to allocate a **large block of memory** (e.g. a large array, or a big struct), and you need to **keep that variable around a long time** (like a global), then you should **allocate it on the heap**.
553
+
>
554
+
> If you are dealing with **relatively small variables that only need to persist as long as the function using them is alive**, then you should **use the stack**, it's easier and faster.
555
+
>
556
+
> If you need variables like arrays and structs that can **change size dynamically** (e.g. arrays that can grow or shrink as needed) then you will likely need to **allocate them on the heap**, and use dynamic memory allocation functions like `malloc()`, `calloc()`, `realloc()` and `free()` to manage that memory "by hand".
0 commit comments