mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-01-11 13:38:24 +00:00
[SPCA] Start pointers
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
\newpage
|
\newpage
|
||||||
\subsubsection{Arrays}
|
\subsubsection{Arrays}
|
||||||
|
\label{sec:c-arrays}
|
||||||
\lC\ compiler does not do any array bound checks! Thus, always check array bounds.
|
\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.
|
Unlike some other programming languages, arrays are \bi{not} dynamic length.
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,18 @@
|
|||||||
|
\newpage
|
||||||
\subsubsection{Pointers}
|
\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}
|
||||||
|
|||||||
Binary file not shown.
@@ -82,4 +82,12 @@
|
|||||||
\section{Hardware}
|
\section{Hardware}
|
||||||
\input{parts/02_hw/00_intro.tex}
|
\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}
|
\end{document}
|
||||||
|
|||||||
Reference in New Issue
Block a user