\section{C Memory Model}

The C memory model is probably unlike most that you've seen before. Instead of allocating an object with type safety, we either use an automatic variable or request a sequence of bytes with \keyword{malloc} or another family member and later we \keyword{free} it.

\subsection{Structs}

In low-level terms, a struct is a piece of contiguous memory, nothing more.
Just like an array, a struct has enough space to keep all of its members.
But unlike an array, it can store different types. Consider the contact struct declared above.

\begin{lstlisting}[language=C]
struct contact {
  char firstname[20];
  char lastname[20];
  unsigned int phone;
};

struct contact person;
\end{lstlisting}

We will often use the following typedef, so we can write use the struct name as the full type.

\begin{lstlisting}[language=C]
typedef struct contact contact;
contact person;

typedef struct optional_name {
  ...
} contact;
\end{lstlisting}

If you compile the code without any optimizations and reordering, you can expect the addresses of each of the variables to look like this.

\begin{lstlisting}[language=C]
&person           // 0x100
&person.firstname // 0x100 = 0x100+0x00
&person.lastname  // 0x114 = 0x100+0x14
&person.phone     // 0x128 = 0x100+0x28
\end{lstlisting}

All your compiler does is say "reserve this much space".
Whenever a read or write occurs in the code, the compiler will calculate the offsets of the variable.
The offsets are where the variable starts at.
The phone variables starts at the \keyword{0x128}th bytes and continues for sizeof(int) bytes with this compiler.
\textbf{Offsets don't determine where the variable ends though}.
Consider the following hack seen in a lot of kernel code.

\begin{lstlisting}[language=C]

typedef struct {
  int length;
  char c_str[0];
} string;

const char* to_convert = "person";
int length = strlen(to_convert);

// Let's convert to a c string
string* person;
person = malloc(sizeof(string) + length+1);
\end{lstlisting}

Currently, our memory looks like the following image.
There is nothing in those boxes

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{introc/drawings/memory_model_empty.eps}
\caption{Struct pointing to 11 empty boxes}
\end{figure}

So what happens when we assign length?
The first four boxes are filled with the value of the variable at length.
The rest of the space is left untouched.
We will assume that our machine is big endian.
This means that the least significant byte is last.

\begin{lstlisting}[language=C]
person->length = length;
\end{lstlisting}

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{introc/drawings/memory_model_length.eps}
\caption{Struct pointing to 11 boxes, 4 filled with 0006, 7 junk}
\end{figure}

Now, we can write a string to the end of our struct with the following call.

\begin{minted}{C}
strcpy(person->c_str, to_convert);
\end{minted}

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{introc/drawings/memory_model_full.eps}
\caption{Struct pointing to 11 boxes, 4 filled with 0006, 7 the stirng ``person''}
\end{figure}

We can even do a sanity check to make sure that the strings are equal.

\begin{minted}{C}
strcmp(person->c_str, "person") == 0 //The strings are equal!
\end{minted}

What that zero length array does is point to the \textbf{end of the struct} this means that the compiler will leave room for all of the elements calculated with respect to their size on the operating system (ints, chars, etc).
The zero length array will take up no bytes of space.
Since structs are continuous pieces of memory, we can allocate \textbf{more} space than required and use the extra space as a place to store extra bytes.
Although this seems like a parlor trick, it is an important optimization because to have a variable length string any other way, one would need to have two different memory allocation calls.
This is highly inefficient for doing something as common in programming as is string manipulation.

\subsection{Strings in C}

In C, we have
\href{https://en.wikipedia.org/wiki/Null-terminated_string}{Null
	Terminated} strings rather than
\href{https://en.wikipedia.org/wiki/String_(computer_science)\#Length-prefixed}{Length
	Prefixed} for historical reasons.
For everyday programmers, remember to NUL terminate your string!
A string in C is defined as a bunch of bytes ended by `\0' or the NUL Byte.

\subsection{Places for strings}

Whenever you define a string literal - one in the form \keyword{char*\ str\ =\ "constant"} -- that string is stored in the \emph{data} section. Depending on your architecture, it is \textbf{read-only}, meaning that any attempt to modify the string will cause a SEGFAULT.
One can also declare strings to be either in the writable data segment or the stack. To do so, specify a length for the string or put brackets instead of a pointer \keyword{char str[] = "mutable"} and put in the global scope or the function scope for the data segment or the stack respectively.
If one, however, \keyword{malloc}'s space, one can change that string to be whatever they want.
Forgetting to NUL terminate a string has a big effect on the strings! Bounds checking is important.
The heartbleed bug mentioned earlier in the book is partially because of this.

Strings in C are represented as characters in memory.
The end of the string includes a NUL (0) byte.
So "ABC" requires four(4) bytes.
The only way to find out the length of a C string is to keep reading memory until you find the NUL byte.
C characters are always exactly one byte each.

\subsubsection{String literals are constant}

A string literal is naturally constant.
Any write will cause the operating system to produce a SEGFAULT. 

\begin{lstlisting}[language=C]
char array[] = "Hi!"; // array contains a mutable copy
strcpy(array, "OK");

char *ptr = "Can't change me"; // ptr points to some immutable memory
strcpy(ptr, "Will not work");
\end{lstlisting}

String literals are character arrays stored in the read-only data segment of the program, which is immutable.
Two string literals may share the same space in memory.
An example follows.

\begin{lstlisting}[language=C]
char *str1 = "Mark Twain likes books";
char *str2 = "Mark Twain likes books";
\end{lstlisting}

The strings pointed to by \keyword{str1} and \keyword{str2} may actually reside in the same location in memory.

Char arrays, however, contain the literal value which has been copied from the code segment into either the stack or static memory.
These following char arrays reside in different memory locations.

\begin{lstlisting}[language=C]
char arr1[] = "Mark Twain also likes to write";
char arr2[] = "Mark Twain also likes to write";
\end{lstlisting}

Here are some common ways to initialize a string include. Where do they reside in memory?

\begin{lstlisting}[language=C]
char *str = "ABC";
char str[] = "ABC";
char str[]={'A','B','C','\0'};
\end{lstlisting}

\begin{lstlisting}[language=C]
char ary[] = "Hello";
char *ptr = "Hello";
\end{lstlisting}

We can also print out the pointer and the contents of a C-string easily. Here is some boilerplate code to illustrate this.

\begin{lstlisting}[language=C]
char ary[] = "Hello";
char *ptr = "Hello";
// Print out address and contents
printf("%p : %s\n", ary, ary);
printf("%p : %s\n", ptr, ptr);
\end{lstlisting}

As mentioned before, the char array is mutable, so we can change its contents.
Be careful to write within the bounds of the array.
C does \emph{not} do bounds checking at compile-time, but invalid reads/writes can get your program to crash.

\begin{lstlisting}[language=C]
strcpy(ary, "World"); // OK
strcpy(ptr, "World"); // NOT OK - Segmentation fault (crashes by default; unless SIGSEGV is blocked)
\end{lstlisting}

Unlike the array, however, we can change \keyword{ptr} to point to another piece of memory,

\begin{lstlisting}[language=C]
ptr = "World"; // OK!
ptr = ary; // OK!
ary = "World"; // NO won't compile
// ary is doomed to always refer to the original array.
printf("%p : %s\n", ptr, ptr);
strcpy(ptr, "World"); // OK because now ptr is pointing to mutable memory (the array)
\end{lstlisting}

Unlike pointers, that hold addresses to variables on the heap, or stack, char arrays (string literals) point to read-only memory located in the data section of the program. This means that pointers are more flexible than arrays, even though the name of an array is a pointer to its starting address.

In a more common case, pointers will point to heap memory in which case the memory referred to by the pointer \textbf{can} be modified.


