Pointers Aren't (that) Hard: A video tutorial by Cody

Hey guys!

I decided to address the dreaded topic of pointers in the C family of languages. Admittedly I kind of threw this together in one take, and I (as usual) have some small slip-ups, but overall I feel like this is good enough to throw out there.

If you want to know a little more about how data is handled in programs, at least on x86, this one is for you.

Pointers Aren’t (that) Hard

Some slipups / clarification

When describing how memory is laid out I kept mixing “bit” when I meant “byte” I eventually realized this, but it was too late. Memory is addressed in terms of BYTES and in terms of BYTES in 32-bit systems 4GB of memory is addressable

To be more clear about the cache-hit / miss analogy. An L1 hit takes about 4 cycles, a complete cache-miss takes 100’s of cycles-ish.

Don’t even try to do pointer arithmetic on void pointers. I said void pointers use 1 byte offsets but it turns out this is compiler dependent.

Example code



// Create a new pointer
// --------------------
// TYPE * NAME;

// IE: Let's create an int pointer...
int * intPtr;

// IE: Let's create a void pointer...
void * voidPtr;

// Assign our int pointer
// ----------------------

// IE: To a regular old value (using the address of operator)
int value = 42;
intPtr = &value;

// Notice how this requires the use of the address of operator (&) because "value" is an int not an address or int pointer.

// IE: To an array
int array[100];
intPtr = array;

// Notice how this doesn't require the use of the address of operator (&) because "array" is secretly an address already or more specifically "arrays decay into pointers"

// Use our int pointer to access (get) various elements of the array
// -----------------------------------------------------------------

// IE: 0th element
int zero = *(intPtr);

// zero gets the value "42" because the dereference operator (*) "reads" the contents of intPtr and assigns that value to zero

// IE: 1st element
int first = *(intPtr + 1);

// IE: 2nd element
int second = *(intPtr + 2);

// IE: 3rd element
int third = *(intPtr + 3);

// Use our int pointer to write (set) various elements of the array
// ----------------------------------------------------------------

// IE: Write the value "105" to the 0th element
*(intPtr) = 105;

// This reads, go to whatever address intPtr points to and SET that space to whatever is on the right side

// IE: Write the value "105" to the 1st element
*(intPtr + 1) = 105;

// IE: Write the value "105" to the 2nd element
*(intPtr + 2) = 105;

// IE: Write the value "105" to the 3rd element
*(intPtr + 3) = 105;

// Declare a struct
// ----------------
typedef struct 
{
	int x;
	int y;
} Vec2D;

// Now we can make one like so...
Vec2D vec;

// And if we wanted to make a pointer to that struct...
Vec2D * vecPtr = &vec;

// Let's access the members of that struct
// ---------------------------------------
vecPtr->x = 1;
vecPtr->y = 2;

int x = vecPtr->x;
int y = vecPtr->y;

// Let's create some dynamic (heap) memory
// ---------------------------------------
Vec2D * vecDynamic = malloc(sizeof(Vec2D));

vecDynamic->x = 1;
vecDynamic->x = 2;

// Finally let's let go of (free) that dynamic memory
// --------------------------------------------------
free(vecDynamic);

Feel free to ask questions below.

-Cody