Memory Thumbnail

Image from CS50, licensed under CC BY-NC-SA 4.0.

Pointers and Dynamic Memory Allocation

C introduces data types that have specific sizes in memory (int , float, long and char ) . If I want to represent the number 47, I typically use an int, which takes 4 bytes in my computer's memory—equivalent to 32 bits. But what if you want the user to input their name? How many char would you need? The answer is: we don’t know, because names vary in length.

Strings

Strings are inherently dynamic, so we needed a strategy to represent them efficiently in memory. To solve this, it was decided to terminate strings with a NUL \0 character. This allowed us to determine where a string ends. Alright, but how do we determine where a string starts? For that, we use pointers, which store memory addresses of variables. So to represent a string, we typically store a memory address (indicating where the string starts) and end it with a NUL character \0.

Arrays

Our second challenge with dynamic data relates to arrays. In C, arrays are not dynamic. If we want to add a new element to an array, we need to allocate new memory, copy all the existing elements into it, and then add the new value. This process is inefficient, especially for large arrays. Once again, pointers come to the rescue. To solve the issue of array dynamism, we use pointers to create linked lists. A linked list is a collection of nodes, where each node contains a value and a pointer to the next node. This approach allows us to dynamically add elements to the list without needing to find a contiguous block of memory, unlike arrays which must be allocated as a single, continuous chunk.

Computer Memory Diagram