diff --git a/semester3/spca/code-examples/00_c/00_basics/05_pointers.c b/semester3/spca/code-examples/00_c/00_basics/05_pointers.c index e69de29..75c8262 100644 --- a/semester3/spca/code-examples/00_c/00_basics/05_pointers.c +++ b/semester3/spca/code-examples/00_c/00_basics/05_pointers.c @@ -0,0 +1,27 @@ +#include +#include + +int main( int argc, char *argv[] ) { + int x = 0; + int *p = &x; // Get x's memory address + printf( "%p\n", p ); // Print the address of x + printf( "%d\n", *p ); // Dereference pointer (get contents of memory location) + *p = 10; // Dereference assign + int **dbl_p = &p; // Double pointer (pointer to pointer to value) + int *null_p = NULL; // Create NULL pointer + *null_p = 1; // Segmentation fault due to null pointer dereference + + // ── pointer arithmetic ─────────────────────────────────────────── + // Already seen a bit in the c arrays section + int arr[ 3 ] = { 2, 3, 4 }; + char c_arr[ 3 ] = { 'A', 'B', 'C' }; + int *arr_p = &arr[ 1 ]; + char *c_arr_p = &c_arr[ 1 ]; + c_arr_p += 1; // Now points to c_arr[2] + arr_p -= 1; // Now points to arr[0] + + char *arr_p_c = (char *) arr_p; // Cast to char pointer (points to first byte of arr[0]) + printf( "%d", *( arr_p - 5 ) ); // No boundary checks (can access any memory) + + return EXIT_SUCCESS; +} diff --git a/semester3/spca/parts/00_c/01_basics/04_arrays.tex b/semester3/spca/parts/00_c/01_basics/04_arrays.tex index 8f9ca15..1671f21 100644 --- a/semester3/spca/parts/00_c/01_basics/04_arrays.tex +++ b/semester3/spca/parts/00_c/01_basics/04_arrays.tex @@ -1,5 +1,6 @@ \newpage \subsubsection{Arrays} +\label{sec:c-arrays} \lC\ compiler does not do any array bound checks! Thus, always check array bounds. Unlike some other programming languages, arrays are \bi{not} dynamic length. diff --git a/semester3/spca/parts/00_c/01_basics/07_pointers.tex b/semester3/spca/parts/00_c/01_basics/07_pointers.tex index ad65d30..c885404 100644 --- a/semester3/spca/parts/00_c/01_basics/07_pointers.tex +++ b/semester3/spca/parts/00_c/01_basics/07_pointers.tex @@ -1 +1,18 @@ +\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} + +\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} diff --git a/semester3/spca/spca-summary.pdf b/semester3/spca/spca-summary.pdf index 238fc53..cb492f4 100644 Binary files a/semester3/spca/spca-summary.pdf and b/semester3/spca/spca-summary.pdf differ diff --git a/semester3/spca/spca-summary.tex b/semester3/spca/spca-summary.tex index be693ad..887a8b1 100644 --- a/semester3/spca/spca-summary.tex +++ b/semester3/spca/spca-summary.tex @@ -82,4 +82,12 @@ \section{Hardware} \input{parts/02_hw/00_intro.tex} +Remember: Rust and the like have an \texttt{unsafe} block... \lC's equivalent to this is +\begin{code}{c} +int main( int argc, char *argv[] ) { + // Unsafe code goes here +} +\end{code} +i.e. \bi{YOU are the one that makes \lC\ code safe!} + \end{document}