Lecture 2026-2-24
Null pointers, undefined behaviour, dynamic arrays, linked-lists (in C, akin to Racket Lists), List Proccess
You will fail test-cases if you have memory-leaks.
Recall:
int *p = malloc(...);
free(p);
failing to free all allocated memory - called a memory leak.int *p = malloc (....);
free (p);
*p = 7;//will this crash? codeprobably not since free(p) doesn't change
ppstill points to that memory, so storing there unlikely to crash - but the location can be given out to another malloc call -> data corruption
called a dangling pointer. BAD
Better: after free(p), assigns p to a guaranteed-invalid location
int *p = malloc(____);
free(p);
p = NULL; // null pointer - points to nothingNULL is NOT part of the C language.
it is defined as a constant ( in the library )equal to 0.
Could equally well say p = 0;
Thus now, p does NOT point to anything.
Deferencing NULL
Undefined behaviour ( UB )
program may crash ( when will it NOT crash )
If malloc fails to allocate memory- returns NULL.
e.g.
Consider again:
Think of the stackframe.



Thus, programs might not crash- but will behave badly.
e.g.
5 replaces 4
data corruption
Never return a pointer to a local variable.
If you want to return a pointer, it should point to static, heap, or non-local stack data.
because THEY DON'T go away !
Use the heap:
For data that should outlive the function that creates it ( when to use static, when to use malloc)
For data whose size is not known at compile-time
For large local arrays.
1) as above ( getMeaPtr)
2)
What if we ask for more memory (arg does NOT have to be constant)?
This leads to dynamic arrays ( why? )
can acess `
p[0],...,p[numSlotsNeeded -1]dynamic array ( heap-allocated)
.....free(p)
Programs typically have more heap memory than stack memory.
This was akin to replicating Racket-like Structs in C ( How?)
Can we get the behaviour of a Racket list in C?
(cons x y) produces a pair x[<- ][->]y ( pointers )
Recall: Racket is dynamically typed.

C is statically typed ⇒ list items would need to have the same type.
(if not ⇒ headache)

So no actual need for ptrs to datafields ( as they were there bc of different types )

Thus how does one "process" a linked list?
OR
Can we write map ( FAVOURITE FUNCTION )
You can pass functions as arguments in functions. But what happens?
The name of a function is a pointer to the function's code.
But note, we have the name and name-definition, but we don't have environment
Due to the "flat-environment" of C, we can get away, sometimes, by NOT using an environment.
Reveals the power of Racket and limitations of C compared to Racket.
But what does f look like?
Since we know that the code coming in we can easily make declaration, and go from there:
We read C declaration from variable then goes outwards, smth smth smth.
Thus
int * f(int), from postfix before prefix, we have a declaration of a function that passes an int and returns a pointer to an int ( int * ).
Exercise: Do it iteratively.
Freeing Linked Lists.
cur = cur -> next happens after free (cur)
cur is dangling
need to grab next pointer before you free.
How do you do that?
we are def getting a problem that asks if a pointer is dangling.
Last updated