Skip to content
This repository was archived by the owner on Oct 27, 2023. It is now read-only.

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

0x0002 Scope, Stack and Heap

Global Scope

C/C++ supports global and static variables. Both global and static variables can be used to store read-only or read-write data. Static variables behave differently depending on where they are declared.

Global variables are stored in a variety of locations in the executable. Constant global or static data are declared in the .TEXT segment of a binary. Uninitialized global or static data are stored in the .BSS segment of a binary. Initialized global or static data are stored in the .DATA segment of a binary. Globals and statics are only deleted when the application exits.

While this doesn't mean a whole lot in practice it's important to know that globals and statics are stored in different locations than other variables.

Block Scope

C/C++ is a block scoped language. This differs from Python in subtle, but important ways. In Python, variables declared in blocks exist for the lifetime of a function.

Blocks can be used in three main settings, function definitions, data structure definitions (both classes and structures), control flow, and anonymous (naked) blocks.

Anonymous blocks are rarely used in practice. They offer more fine grained control over the lifetime of variables. Check out this example to see anonymous blocks in action.

All variables defined within a block are defined on the stack.

Stack

The stack is a region of memory where block scoped variables live. The stack is also responsible for containing function call frames. The stack starts at a high address and moves down.

All variables declared on the stack will be cleared when they leave scope. Most often this is due to the end curly brace of a function or control flow construct. Throwing an exception will end scope of the variables within a function (will cover exceptions later).

The stack

Functions

Function calls are defined in a processor's Application Binary Interface (ABI). Most ABI's allow for a limited amount of arguments to be passed via general purpose registers instead of being placed on the stack.

In terms of memory allocation, registered data and stack data perform exactly the same. When the scope is left the variables are cleared. There are just fewer instructions needed to use data contained in registers.

Heap

Variables with longer lifetimes than a single scope are declared on the heap. The heap is a section of memory sandwiched between code and the stack. The heap starts at a low address and moves upward.

Heap is used by creating space for data, initializing that data, and storing a pointer to that data. Initialization of objects is handled by the objects constructor (will be covered later).

C and C++ have different mechanisms for creating space on the heap. C uses a function called malloc, C++ uses an operator called new.

Because data declared on the heap never goes out of scope, it must be cleaned manually. C and C++ also have different mechanisms for deleting objects created on the heap. C uses free and C++ uses delete.

Raw Pointers

As illustrated in the previous examples, pointers are used to store the address of data on the stack. Pointers and the data they point to can be manipulated in a variety of ways.

The previous example briefly touches on some of the ways pointers can be manipulated. Modern C++ discourages the use of raw pointers; smart pointers or references should be used instead.

Additional References

System V Application Binary Interface