mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-01-11 19:48:27 +00:00
52 lines
3.4 KiB
TeX
52 lines
3.4 KiB
TeX
\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 later). % TODO: Link to correct section
|
|
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}
|
|
|
|
Note that when doing pointer arithmetic, adding $1$ will move the pointer by \texttt{sizeof(type)} bits.
|
|
|
|
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{orange}{Fun fact}: \texttt{A[i]} is always rewritten \texttt{*(A + i)} by compiler.
|
|
|
|
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.
|
|
|
|
Another interesting concept that \lC\ has to offer is body-less loops:
|
|
\begin{code}{c}
|
|
int x = 0;
|
|
while ( x++ < 10 ); // This is (of course) not a useful snippet, but shows the concept
|
|
\end{code}
|
|
|
|
\lC\ also has an option to pass functions as arguments to functions, called function pointers.
|
|
A function is passed 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, ...)|.
|