\newpage
\subsubsection{Pointers}
On loading of a program, the OS creates the virtual address space for the process, inspects the executable and loads the data to the right places in the address space,
before other preparations like final linking and relocation are done.

Stack-based languages (supporting recursion) allocate stack in frames that contain local variables, return information and temporary space.
When a procedure is entered, a stack frame is allocated and executes any necessary setup code (like moving the stack pointer, see \ref{sec:asm-stack}).
When a procedure returns, the stack frame is deallocated and any necessary cleanup code is executed, before execution of the previous frame continues.

\bi{In \lC\ a pointer is a variable whose value is the memory address of another variable}

Of note is that if you simply declare a pointer using \texttt{type * p;} you will get different memory addresses every time.
The (Linux)-Kernel randomizes the address space to prevent some common exploits.
\inputcodewithfilename{c}{}{code-examples/00_c/00_basics/05_pointers.c}

\newpage
\begin{scriptsize}
    Some pointer arithmetic has already appeared in section \ref{sec:c-arrays}, but same kind of content with better explanation can be found here
\end{scriptsize}

\content{Pointer Arithmetic} Note that when doing pointer arithmetic, adding $1$ will move the pointer by \texttt{sizeof(type)} bits.
Pointer arithmetic with a \texttt{void} pointer is thus not allowed by standard \lC, as the compiler does not know the size of the data type.
However, \texttt{gcc} does allow it and assumes the size of \texttt{void} is \texttt{1 byte}.

You may use pointer arithmetic on whatever pointer you'd like (as long as it's not a null pointer).
This means, you \textit{can} make an array wherever in memory you'd like.
The issue is just that you are likely to overwrite something, and that something might be something critical (like a stack pointer),
thus you will get \bi{undefined} behaviour! (This is by the way a common concept in \lC, if something isn't easy to make more flexible
(example for \texttt{malloc}, if you pass a pointer to memory that is not the start of the \texttt{malloc}'d section, you get undefined behaviour),
in the docs mention that one gets undefined behaviour if you do not do as it says, so\dots RTFM!)

As already seen in the section arrays (section \ref{sec:c-arrays}), we can use pointer arithmetic for accessing array elements.
The array name is treated as a pointer to the first element of the array, except when:
\begin{itemize}[noitemsep]
    \item it is operand of \texttt{sizeof} (return value is $n \cdot \texttt{sizeof(type)}$ with $n$ the number of elements)
    \item its address is taken (then \texttt{\&a == a})
    \item it is a string literal initializer. If we modify a pointer \texttt{char *b = "String";} to string literal in code,
          the \texttt{"String"} is stored in the code segment and if we modify the pointer, we get undefined behaviour
\end{itemize}
\shade{purple}{Fun fact}: \texttt{A[i]} is always rewritten \texttt{*(A + i)} by compiler.

\content{Function arguments} Another important aspect is passing by value or by reference.
You can pass every data type by reference, you can not however pass an array by value (as an array is treated as a pointer, see above).

\content{Body-less loops}
\rmvspace
\begin{code}{c}
    int x = 0;
    while ( x++ < 10 ); // This is (of course) not a useful snippet, but shows the concept
\end{code}

\content{Function pointers}
A function can be passed as an argument to another function using the typical address syntax with the \verb|&| symbol is annotated as argument using
\verb|type (* name)(type arg1, ...)|
and is called using \verb|(*func)(arg1, ...)|.
