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.
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