Skip to content

Instantly share code, notes, and snippets.

@gubatron
Last active October 10, 2018 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gubatron/9189e38886609e275627aeb0d0165f0f to your computer and use it in GitHub Desktop.
Save gubatron/9189e38886609e275627aeb0d0165f0f to your computer and use it in GitHub Desktop.
movePointer.cpp - on how arrays are passed to functions and how we can do something similar with pointers to them
// A short lesson on pointers and arrays in C++
// Author: Angel Leon - October 9th 2018
#include <iostream>
#include <string>
using namespace std;
int main() {
// define some string array with a few strings
string someArray[] = { "Nicole", "Leon", "Molina" };
// get a pointer to the first element in the array
// (when you pass an array to a function, the function basically gets
// a pointer to the first element of the given array, passing an array
// does not copy the array to the function's stack memory region)
// in this code sample we're going to do what a function does when it receives
// a parameter, manually, and then we're going to move along the array by moving
// the pointer forward and reading what it's pointing to,
// instead of using the array's `[]` indexOf operator.
string *arrayPointer = (string*) &someArray;
// `&someArray` returns the memory address of the first element in the array
// '(string*)' casts that number into a string pointer, so we can assign it to `arrayPointer`
// let's print `arrayPointer`
cout << "arrayPointer -> " << arrayPointer << endl; // Prints something like -> 0x7ffee548d4a0, the memory address.
// if what I said is true, and we printed the memory address of `someArray[0]`, it should be the same
cout << "&someArray[0] -> " << &someArray[0] << endl; // Should print the same number as above -> 0x7ffee548d4a0
// note, this number should change everytime you run the program, but it should be the same for those
// 2 prints above, this is because, your program doesn't always get the same memory available,
// the operating system is always managing memory for all the different processes.
// now let's print what's being pointed to (the first element), for this, we "de-reference" the pointer using the `*` operator
cout << "*arrayPointer -> " << *arrayPointer << endl; // Should print "Nicole"
// now let's move the pointer 1 position
// before we move though, let's write down the memory address, so we can do a little math later and we know
// how many bytes we're moving forward as we jump through the array
long firstMemoryAddress = (long) arrayPointer;
// let's print that, it should be the same as &someArray[0] too
cout << "firstMemoryAddress -> " << std::hex << firstMemoryAddress << endl; // Should print again -> 0x7ffee548d4a0
// (std::hex is so that it prints it in hexadecimal, otherwise it prints the number in decimal)
arrayPointer++; // notice that we're adding 1, pointer arithmetic makes this easy, it does so knowing the byte count
// needed to move one position along the array, it knows so because it knows it's a pointer to string
// if it were a pointer to int, it would move automatically 4 bytes
// and let's print again
cout << "*arrayPointer -> " << *arrayPointer << endl; // Should print "Leon"
// Let's see the memory address now, should be different, should be the same as someArray[1]'s
cout << "arrayPointer -> " << arrayPointer << " - &someArray[1] -> " << &someArray[1] << endl;
// If we subtract the current memory address vs the first one, we'll know how many bytes the pointer
// is actually moving based on the pointer's type data size.
long memoryDelta = ((long) arrayPointer) - firstMemoryAddress;
cout << "memoryDelta -> " << memoryDelta << endl; // 18 bytes
// what's the size of the 'string' data type representation (not 'a string')?
cout << "sizeof(string) -> " << sizeof(string) << endl; // yup, 18 bytes
// 18 bytes because std::string is a class with members, functions and yes, a pointer to char*
// which is the actual string data, so your string array, is really an array of fancy pointers to char* along with some other things.
// if I were to implement the [i] operator for array in C++, I'd basically multiply the
// size in bytes of the array's data type, in our case `sizeof(string)` times the given index `i`
// and move in memory that byte-distance from the first element's memory position.
// This is a single operation and this is why you hear that array lookup (given an index) happens in constant time,
// no matterhow big the array is, it's a simple multiplication and addition, blazing fast lookup.
// hope this makes sense.
// now for fun, try moving the pointer 2 more times and see what happens :)
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment