WHAT ARE POINTER?!
Stupid Ecto…
I’m now nearly three months in to my first “proper” job (I’ve had jobs before, but this is the first time I’ve had a job and’ve had to actually spend my own money to, y’know, stay alive). It’s been fun so far, my wide-eyed enthusiasm for fucking everything has been fairly entertaining for my coworkers.
The major thing that’s changed in the last three months is essentially relearning what I know about programming – not core stuff (I can write a mean for loop), but when you’ve got limited amounts of memory, or have to assume you have limited amounts of memory because of what’s running on the system, you suddenly have to stop using “new” randomly and actually watch what you’re doing.
In first year of my undergrad, we were taught the basics of programming in C – the true basics, arrays, loops, linked lists, binary search trees (which I’ve not used since). The first half of second year was taken up “advanced” C++, classes, exception handling, the stl, but the lecturer had a habit of either sending us to sleep or confusing us. I finally understood what classes were a few days before the exam, when I opened the programming book we’d been instructed to buy in first year. I finally understood classes properly three years later during my masters. We were taught pointers at some point, I don’t recall if it was the first or second year – probably the first.
Pointers and classes were always the two sticking points for most of our class (excluding the people, who, in their final year still didn’t quite understand arrays – I watched another, also in the final year, wonder why a mashup of an if statement and do/while in a single statement wouldn’t compile). The idea of “this thing is pointing to this other thing, but you can change where it points, you can manually change the address and you can change the value, all separately” was fairly confusing – even during my final year project (which I can’t go near as I remember how awful the coding was), a lecturer asked me if I’d used pointers “No, they confuse me” – “Good, they confuse me too”. Classes were a sticking point simply as they were badly taught.
So here’s a simple tutorial on classes, and a slightly longer one on pointers:
Classes are structs, but with more stuff. You can have functions (methods technically, I think) within a class, a function (you can define) is called when you create a class, and a second one is called when you destroy the class. Apart from some stuff like inheritance and the visibility of members, that’s about all there is to it. Easy!
Pointers are slightly more difficult, and require a bit of a conceptual rethink (they did for me at least) – you’ve to think of something like “new int” as “I’ve just said I want space for an int”, rather than “I’ve just created an int”. For this reason, I found it easier to work with malloc instead of new (though if you’re using C++, you’d better stick with new – as far as I know, malloc doesn’t play nice with objects), as malloc allows you to specify the size in bytes of the memory you want to reserve.
So say you want a pointer to an int (not terribly useful, but we’ll start off there) –
malloc(sizeof(int));
Again, it’s important to point out that this isn’t saying “wooo, int!”, it’s saying “I want some memory that’ll hold an int”. Malloc returns a void * which can be cast to anything, so in order for it to be usable, you’ve to do something like
(int *)malloc(sizeof(int));
“I want some memory that’ll hold an int, and I’m telling you it’s going to hold an int”
As sizeof() just returns a number, technically the following is still correct, though bad practice:
(unsigned int *)malloc(sizeof(int));
But back to what we were doing:
int * A = (int *)malloc(sizeof(int));
“I want some memory that’ll hold an int, I’m telling you it’s an int, and I’m going to reference it as an int, using A”
*A = 97;
“Put the decimal digit 97 into the memory location A points to”
printf(“A = %dn”, *A);
“Print out the memory location A points to, it’s a decimal”
A = 97
printf(“A = %cn”, *A);
“No, wait, the memory location actually holds a char”
A = a
This isn’t the best example – the code would still perform in the same way if an explicit int was used, but the concept is to demonstrate the system only knows what’s in a memory location because you tell it.
Where I found it to be incredibly handy was for a linked list I created during the week. The list has to have a “core” type (a struct) that contains basic information (few ints) and a pointer to the next element of the list – a pointer to another “core” type. The problem arose as I needed multiple different types of structs in the list – a different one for int, bool etc – the next pointer needs to be able to point to any of these structs, but it can only be defined as pointing to a “core” struct (unless you were to do something super messy, involving checking what type of struct the next one was before linking it).
I got around this by myalloc’ing whatever size I needed for the appropriate structure (say it’s 32 bytes), setting the appropriate values, then casting (“Y’know that memory location? It’s actually a core struct, not a bool struct”) it to the core type (say 24 bytes), and linking it up to the next pointer. As the entire 32 bytes have been reserved by the system, the variables kept in the extra 8 bytes stay intact no matter what you do to the other 24 (as long as you don’t free!), so when you need the extra data, you can just recast (“Y’know that memory location? It’s not a core struct, it’s actually got a bool there”) and you’re done. The first 24 bytes do need to be the same, however, or you will run into trouble.
And that’s pointers.
Course, some of that might’ve been wrong, but it’s been good to write everything down. Even while writing it though, I’ve thought of ways to redesign the list – that’s the problem with learning, every few days, you find a better way to do something…