Post

Memory

Memory

Key Terms

  • Bit

Short for binary digit, a bit is a fundamental unit of information in Computer Science that represents a state with one of two values, typically 0 and 1.

Any data stored in a computer is, at the most basic level, represented in bits.


  • Byte

A group of eight bits. For example, 01101000 is a byte.
A single byte can represent up to 256 data values (28).
Since a binary number is a number expressed with only two symbols, like 0 and 1, a byte can effectively represent all the numbers between 0 and 255, inclusive, in binary format.

The following bytes represent the numbers 1, 2, 3 and 4 in binary format.

1: 00000001
2: 00000010
3: 00000011
4: 00000100

Every bit position from right to left represents an increasing power of 2, starting from 20. This is the standard binary positional notation. Note that endianness is a separate concept that refers to the ordering of bytes (not bits) in multi-byte values.


  • Fixed-Width Integer

An integer represented by a fixed amount of bits. For example, a 32-bit integer is an integer represented by 32 bits (4 bytes), and a 64-bit integer is an integer represented by 64 bits (8 bytes).
The following is the 32-bit representation of the number 1, with clearly separated bytes.
00000000 00000000 00000000 00000001


The following is the 64-bit representation of the number 10, with clearly separated bytes.
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001010

Regardless of how large an integer is, its fixed-width-integer representation is, by definition, made up of a constant number of bits.
It follows that, regardless of how large an integer is, an operation performed on its fixed-width-integer representation consists of a constant number of bit manipulations,
since the integer is made up of a fixed number of bits. So an integer equal to 1 will take the same amount of memory as 2147483647.


Memory

Broadly speaking, memory is the foundational layer of computing, where all data is stored.

It’s important to note the following points:

  • Data stored in memory is stored in bytes and, by extension, bits.
  • Bytes in memory can “point” to other bytes in memory, to store references to other data.
  • The amount of memory that a machine has is bounded, making it valuable to limit how much memory an algorithm takes up.
  • Accessing a byte or a fixed number of bytes (like 4 bytes or 8 bytes in the case of 32-bit and 64-bit integers) is an elementary operation, which can be loosely treated as a single unit of operational work.
  • A memory slot can fit 8 bits, which is 1 byte. For example, a 32-bit integer would take 4 memory slots.
  • A memory slot can store an address to another memory slot; that is called a pointer. On a 32-bit system, a pointer occupies 4 bytes; on a 64-bit system, it occupies 8 bytes.
  • When you are storing an integer in languages like C, C++, or Java, it is typically a fixed-width integer, meaning it’s either 8, 16, 32, or 64 bits. The point is that we know exactly how many bytes it will take up. Note that some languages, such as Python, use arbitrary-precision integers that can grow as large as memory allows.
  • If a value takes more than one memory slot, the required number of contiguous memory slots are allocated back to back to store it.
  • Storing a list works similarly. If you want to store a list of five 32-bit integers, for instance, that list is going to occupy 20 memory slots.

Strings and Character Encoding

Not all data is numeric. Strings, for example, are stored as sequences of encoded characters. A common encoding is ASCII, which uses 1 byte per character and covers 128 characters (letters, digits, punctuation). Modern systems typically use UTF-8, a variable-width encoding that is backward-compatible with ASCII. In UTF-8, a character can take anywhere from 1 to 4 bytes — standard Latin letters take 1 byte each, while characters from other scripts (e.g., Chinese, Arabic, emoji) may take 2, 3, or 4 bytes. The string “hello” in ASCII/UTF-8 occupies 5 bytes, one per character.

Stack vs Heap Memory

At runtime, memory is broadly divided into two regions: the stack and the heap. The stack is used for static memory allocation — function call frames, local variables, and return addresses. It is fast because allocation and deallocation follow a strict last-in-first-out order. The heap is used for dynamic memory allocation — objects, arrays, and data structures whose size may not be known at compile time. Heap allocation is more flexible but comes with overhead: the program must explicitly request and release memory (or rely on a garbage collector). Understanding where your data lives helps explain performance characteristics and potential pitfalls like stack overflows or memory leaks.

This post is licensed under CC BY 4.0 by the author.