Lesson 2
Review
Multidimensional arrays
What we want
You wanna get this:
So each of “first layer” of arrays is a pointer to the first value of an array.
Remember, a[1][2] = *(*(a+1)+2)
One Way
Another way to do this is to create a one-dimensional array containing pointers to CERTAIN POINTS in another one dimensional array. Not actually a 2 dimensional array, but it does have the same effect.
Let's elaborate.
int ** a = (int**) malloc(size1*sizeof(int*));
int * data = (int*) malloc (size1*size2*sizeof(int));;
for(i=0;i<size1;++i)
{
a[i] = data+size2;
}
//You can now use a[1][2] to access values.
//Order of deletes does not matter.
free(data);
free(a);
int * data = (int*) malloc (size1*size2*sizeof(int));;
for(i=0;i<size1;++i)
{
a[i] = data+size2;
}
//You can now use a[1][2] to access values.
//Order of deletes does not matter.
free(data);
free(a);
Another Way
Have each pointer in an array pointing to a newly allocated array somewhere in memory.
But doing this fucks with the cache. Which leads us nicely to...
Cache
Try not to fuck with the cache. As much as possible, try accessing stuff continguously. If you really can't, whatever. But the cache is fast, so try to take advantage of its Sanic the Hedgehog capabiltiies.
Compilation Process
Let's refresh. There are 3 steps: Preprocessing, Compilation and Linking.
Here's an overly simplistic overview of the steps:
Preprocessing:
Check the preprocessor commands. You know, the hashtag shit.
Compilation:
Compile the code into individual object files. At this stage they are still not connected to each other.
Linking:
Glue shit togeter. For example, the object files have different relative addresses for the functions now that we're linking them together, so we gotta modify the other object files in relation to this.
Why not to put definitions in the header file
The compiler actually checks the time of compilation - If, for example, the .c was changed, then yeah, recompilation, but only for that thing - .h files being modified would cause recompilation of all the files in the project.
This is also why your shit gets fucked super hard whenever you're transferring stuff from a computer to another computer with a different time - the .exe creation time is also checked.
Another reason is you're messing with the standard. Don't be a dick. To others, but also to yourself. Cause that's what you will be doing.
Functions and Parameters
Just a healthy reminder that by default, parameters are pass-by-value, which means that they are copied. You should really know this by now, but it's easy to forget.
Remember that in C, pass-by-value is the only option. Yeah, you can pass a pointer in, but it's still just a pointer in the function stack. Same thing.
Try not to use pointers as parameters
It may seem convenient, but from a debugging point of view, if one part is fucked and you use pointers as parameters for like 20 function calls, then yeah. Time to search through all that shit.
References
I won't write a lot of detail here because you are all pretty familiar with references - but here are a few useful notes.
- Pass by reference is implemented through pass by pointer.
- However, it is SAFER than pass by pointer. Remember, you can't change what a reference is pointing to. It's basically a top-level const pointer. (int * const)
Dangling pointers and references
We all know what a dangling pointer is. It's a pointer that points to deallocated or uninitialized memory.
Can you have a dangling reference? It's harder, but apparently you can.
p = new int(1);
int & r = *p;
delete p;
int & r = *p;
delete p;
On the same topic, obviously don't take the address of a temporary variable. Lifetime of the temporary variable exists approximately the amount of time required to evaluate or use it. Then it accepts the sweet embrace of death, and so do you, cause you took the address of it.
Fun fact: If you use an “int const &” and assign a temporary variable to it, then the lifetime of the temporary variable is extended for the duration of the reference.