Day 5-15: Stack, BST, and Linked List (CodeReview is awesome)
I have not abandoned you C. But I get impatient quite easily, and wanted to jump ahead to some greater and more dreadful foes.
For my first, I chose the Stack. A stack is a first on, last off data structure. I discovered there are no generics in C, or, rather, C programmers don’t find generics particularly useful. I created a stack of *int*s. I posted all of my solutions on codereview stackexchange, which is a fantastic place to post working code that you’d like checked for best practices and style.
I think the decision to post on codereview accelerated my learning in the art of C tremendously - I was given immediate feedback for my work and felt like I was part a discussion. Being able to jump into a community like that was refreshingly helpful.
Here is my int stack. I used a pointer to a pointer to represent the stack. This way, the head of the stack can easily be switched out, and the outer pointer never changes.
I was using an
is_empty boolean for my plates - some codereviewers suggested I just check for the NULL pointer, which feels wrong to the Java side of my brain.
Memory allocation is interesting, and what makes programming in C such a unique experience.
malloc(X) means allocate a block of memory the size of datatype X, and return a pointer to it.
When I first learned about
malloc I was struck with a thought: why don’t I always have to do this? When do I have to manually allocate memory? Because doing
int x = 5; int *pX = &5; is valid, and I did no manual allocation.
malloc in two situations. They are somewhat related. You allocate a block of memory when you know you are going to need space for an object, but you don’t have that object at that particular moment. This leads to the second purpose - which has to do with scope and localization. If you want your program as a whole to reference a piece of data that is being created within a function, you cannot just instantiate and assign a variable within a function. That variable will only be visible in that scope.
So you use
malloc, which creates this free, global memory for you to use, and returns a pointer. You can do what you wish with this pointer. This was especially useful in
stack, where I had
push, which took an int and added that “plate” to the top of the stack. The “plate” (or block of memory) needed to be referenced outside of that function.
The best/worst part is
free(), which frees that block of memory. It’s depressingly easy to forget to
free() memory you have allocated, and that’s what leads to memory leaks.
But it’s power, in the end. The more power I have with the computer, the more I feel like a programmer. At the end of the day, the computer is doing exactly what I want it do with C. Which can be awful, but also satisfying.