I am learning C in 2020 – Beginner - What I learned about memory, variables and pointers in c
Tags: c, codenewbie, beginners
Published: 2020-05-06 07:05:00

Original Post : <a href="https://ajalacomfort.com/i-am-learning-c-in-2020-beginner-what-i-learned-about-memory-variables-and-pointers-in-c/">HERE</a>
Book: <strong>Head First C</strong>

Chapter: <strong>3</strong>


Platform used: <a href="https://cplayground.com">cplayground.com</a>
<h2 style="text-align: center;"><strong>Pointers humbled me</strong></h2>
<h2>Problem</h2>
<h3><strong><span style="text-decoration: underline;">Goal</span></strong></h3>
Understand pointers at a foundational level.
<h2>Memory Zones in C</h2>
I figured it would be useful to gain a simple overview of where variables could live during the run of a c program.
<h3>Stack</h3>
Variables declared or/and initialised within a function are said to live the stack memory. Note that once the function is called and completes its task, all the local variables cease to exist in the stack memory. Based on several articles I have read and listed below, each local variable ( within the scope of a function) is pushed into the stack memory. Although the stack variables are pushed into the stack memory ( downward growth of stack or in a last-in-first-out manner ), they are removed via a POP function. This denotes the organized process in stack variable management.
<h3>Heap</h3>
Unlike stack variables, heap variables are allocated in a more disorganized manner. Heap variables are created dynamically by using the inbuilt <em>malloc </em>function and removed or their memory allocation freed by the <em>free </em>function. To access heap variables, pointers are used.A really cool thing about heap variables is that since they are dynamically allocated, they can be accessed outside the context of a function using their pointers.
<h3>Static</h3>
These are variables that retain their value even after the function is complete. Additionally after the first initialisation of a declared static variable, subsequent initialisations in the same scope/ function are ignored. Keep in mind that uninitialized static variables are set to 0; The code snippet below demonstrates this:
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;


void foo(){
    
    static int num = 5; // initialized 
    printf("The value of the static local NUM in foo() is %d\n", num);
    num++;
}

void doo(){
    int num = 5; // initialized 
    printf("The value of the local NUM in doo() is %d\n", num);
    num++;
}

void moo(){
    static int num; // uninitialized 
    printf("The value of the static local NUM in moo() is %d\n", num);
    num++;
}
int main() {
        
        for(int i; i &lt; 5; i++){
            foo();
            doo();
            moo();
printf("...................................................\n\n");
        }
    return 0;

}</pre>
<strong>Run…</strong>
<pre class="prettyprint">The value of the static local NUM in foo() is 5
The value of the local NUM in doo() is 5
The value of the static local NUM in moo() is 0
...................................................

The value of the static local NUM in foo() is 6
The value of the local NUM in doo() is 5
The value of the static local NUM in moo() is 1
...................................................

The value of the static local NUM in foo() is 7
The value of the local NUM in doo() is 5
The value of the static local NUM in moo() is 2
...................................................

The value of the static local NUM in foo() is 8
The value of the local NUM in doo() is 5
The value of the static local NUM in moo() is 3
...................................................

The value of the static local NUM in foo() is 9
The value of the local NUM in doo() is 5
The value of the static local NUM in moo() is 4
...................................................</pre>
However static and global variables neither live in the stack nor in the heap memory. They are said to be stored in another area.
<h3>Text Segment</h3>
Also known as the code segment, is the portion of a program where the executables or bytecode instructions of the program lives. Constants also reside in this memory.
<h3>Data Segment</h3>
<h4>Initialized data segment</h4>
Here exist all the global and static variables ( global and local statics) of a program. This segment is not read-only, meaning variables stored here can be re-initialized or assigned new values.
<h4>Uninitialized data segment</h4>
Also called the bss segment, holds variables that were not given values by the programmer and consequently all set to zero.

<em>To be frank, I can't say I fully grasp these concepts as I am new to these, but hopefully it helps you a bit.</em>
<h3>Exercise</h3>
Where are the following variables stored ?
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
int globalInt;
int intializedInt = 23;
static int initializedStaticInt = 11;
int main() {
   static int staticInt = 5;
    int unIntializedInt;
    int val  = 3;
    char name[] = "Comfort Ajala";
    char list[32];
    char initList[32] =  {0}; 
    char * allocatedforchar = (char * ) malloc(20* sizeof(char));
    char *lastname = "Ajala";
    return 0;

}</pre>
<h3>My Solution</h3>
<strong>globalInt → </strong>an uninitialized global variable → <span style="text-decoration: underline;">BSS</span>

<strong>intializedInt</strong> → initialized global variable → <span style="text-decoration: underline;">Initialized data segment</span>

<strong>initializedStaticInt </strong>→ initialized global static variable → <span style="text-decoration: underline;">Initialized data segment</span>

<strong>staticInt </strong>→ initialized static local variable → <span style="text-decoration: underline;">Initialized data segment</span>

<strong>unIntializedInt </strong>→ uninitialized local variable → <span style="text-decoration: underline;">stack</span>

<em>“Only variables with static storage duration end up in .bss and .data. Local variables always end up on the stack, or in CPU registers, no matter if they are initialized or not.” - <a href="https://stackoverflow.com/a/47301825/5386933">Lundin</a></em>

<strong>Val </strong>→ initialized local variable → <span style="text-decoration: underline;">stack</span>

<strong>Name </strong>→ initialized local variable → <span style="text-decoration: underline;">stack</span>

<strong>List </strong>→ uninitialized local variable ( static array ) → <span style="text-decoration: underline;">stack</span>

<strong>initList </strong>→ initialized local variable → <span style="text-decoration: underline;">stack</span>

<strong>Allocatedforchar </strong>→ initialized local variable ( dynamic array ) → <span style="text-decoration: underline;">heap</span>

<strong>Lastname </strong>→ initialized local variable → <span style="text-decoration: underline;">stack</span>

<em>The string literal does not live in the stack though, it is stored in read-only memory. Read <a href="https://stackoverflow.com/questions/12795850/string-literals-pointer-vs-char-array">here </a>for more.</em>
<h2>Variable</h2>
Which can be of type integer ( int), float, char etc stores of a value of the designated type at a specific address.
<h3>Memory address</h3>
According to this <a href="http://www.cs.ecu.edu/karl/3300/spr14/Notes/C/Memory/memory.html">article</a>, memory is a place where variables are stored while a program is running. I am curious about what happens when the program stops. Does the memory disappear ?

The machine memory is apparently a list of bytes, where each byte,a collection of 8 bits, is a unique address. However depending on the type of data stored, a single byte or a group of bytes may be used.This means, the number of bytes used to store an integer or a long value may differ from that used to store a character. It is also important to keep in mind that the size or number of bytes for storage may also vary based on operating systems/ platforms. The address of a given variable, which is also referred to as a <strong>pointer</strong>, can be accessed by using &amp;.
<table>
<tbody>
<tr>
<td>Variable type</td>
<td>Size(byte)</td>
<td>Size (bit)</td>
</tr>
<tr>
<td>int</td>
<td>2 or 4 bytes</td>
<td>16 or 32 bits</td>
</tr>
<tr>
<td>long</td>
<td>8 bytes</td>
<td>64 bits</td>
</tr>
<tr>
<td>char</td>
<td>1 byte</td>
<td>8 bits</td>
</tr>
</tbody>
</table>
<h3>Example…</h3>
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
    size_t sizeofachar = 10 * sizeof(char);
    printf("size of char %li\n How many bytes will be allocated for 10 characters = %li\n", sizeof(char), sizeofachar);
    
    
     size_t sizeofint = 10 * sizeof(int);
    printf("size of int %li\n How many bytes will be allocated for 10 integers  = %li\n", sizeof(int), sizeofint);
    
    
     size_t sizeoffloat = 10 * sizeof(float);
    printf("size of float %li\n How many bytes will be allocated for 10 floats = %li\n", sizeof(float), sizeoffloat);
    
    //%li --&gt; signed integer
    return 0;
}</pre>
<h3>Result</h3>
<pre class="prettyprint">size of char 1
 How many bytes will be allocated for 10 characters = 10
size of int 4
 How many bytes will be allocated for 10 integers  = 40
size of float 4
 How many bytes will be allocated for 10 floats = 40</pre>
<h4>Zum Beispiel…</h4>
When you create a variable of type int and give it a value, the computer looks at the type, determines how many bytes are required for that type based on the OS, selects the byte or bytes, throws the value in and locks the door. Our value is stored and secured.
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;


int main(){
	
	int integer = 3;
	printf("The variable 'integer' is stored at address %p\n", &amp;integer);
	printf("The variable holds value %i\n", integer);
	return 0;
}</pre>
When ran, looks like this:
<pre class="prettyprint">C:\Users\....\practice\c&gt; &amp; cmd.exe /c "gcc practice.c -o a &amp;&amp; a"  
The variable 'integer' is stored at address 0061FF1C
The variable holds value 3</pre>
<h2>Indirection operator</h2>
This unary operator (*),when used on a pointer, helps us access the value that is pointed at by the pointer. Whew… so many points.
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
    int favnumber = 6;
    int * ptr = &amp;favnumber;
    printf("What value does the variable ptr hold ? = %p\n", ptr);
    printf("What value does the variable ptr point to ? = %d\n", * ptr);
    printf("Is the pointer's home address, %p, identical to that of the favnumber's address, %p, ?\n", &amp;ptr, ptr);
    //%p --&gt; format specifier for address of pointers or any variable (void *)
    //%d ---&gt; informs printf to treat the incoming value as an integer
    return 0;
}</pre>
<strong>Result…</strong>
<pre class="prettyprint">What value does the variable ptr hold ? = 0x7ffe30cb607c
What value does the variable ptr point to ? = 6
Is the pointer's home address, 0x7ffe30cb6080, identical to that of the favnumber's address, 0x7ffe30cb607c, ?</pre>
<h2>The “char”</h2>
<pre class="prettyprint">char character = 'n';</pre>
<strong>Where in memory does the character variable live ?</strong>

If declared in a function → <span style="text-decoration: underline;">stack</span>

If declared outside a function → global → <span style="text-decoration: underline;">data segment</span>
<h3>The “char” pointer variable</h3>
<pre class="prettyprint">char *firstchar = 'c';
char *message = "every good boy does fine";</pre>
<strong>Where in memory do these variables live ?</strong>

If declared in a function → <span style="text-decoration: underline;">stack</span>

If declared outside a function → global → <span style="text-decoration: underline;">data segment</span>

<strong>Where do each pointer point to ?</strong>

Let’s log everythang..
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
  char *firstchar = 'c';
char *message = "every good boy does fine";
printf("*firstchar points to %p\n", firstchar);
printf("*message points to %p while the first character of the constant string lives in %p\n", message, &amp;message[0]);
    return 0;

}
                   Compiled in 192.949 ms                   
                        Executing...                        
*firstchar points to 0x63
*message points to 0x4005c8 while the first character of the constant string lives in 0x4005c8</pre>
As you can see, these pointers point to the first character of the given string
<pre class="prettyprint">message[0] = 'm';
*message[0] = 'm';
*(&amp;message[0]) = 'm';</pre>
<strong>Why would the above expression not work?</strong>

Because the pointer points to a string literal, an unmodifiable value. I was a bit confused by the pointer myself, since I always associated POINTERS with MODIFIABLE. But apparently this pointer here only means one can bind the pointer to another string literal. For instance :
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
  char * message  = "every good boy does fine";
  printf("1. Where does message point to &lt;%s&gt; at address %p\n", message, message);
  message = "Just another string";
  printf("2. Where does message point to &lt;%s&gt; at address %p\n", message, message);
    return 0;

}
1. Where does message point to &lt;every good boy does fine&gt; at address 0x4005d8
2. Where does message point to &lt;Just another string&gt; at address 0x40062b</pre>
<strong>How does this pointer know the length of the string literal? </strong>

I assume it uses '\0' or NULL characters to determine the end of the string. <a href="https://stackoverflow.com/questions/1392200/sizeof-string-literal">Read here</a>
<h3>The char array</h3>
<pre class="prettyprint">char notes[] = "every good boy does fine";</pre>
<strong>Where do notes live in memory?</strong>

If declared in a function → <span style="text-decoration: underline;">stack</span>

If declared outside a function → global → <span style="text-decoration: underline;">data segment</span>

Here the program allocates 25 bytes ( 1 char → 1 byte ) for the 24 characters and the terminating character.
<pre class="prettyprint">notes[0] = 'E';</pre>
<strong>Why can I change the character at index 0 of notes but not do the same in the message pointer variable above ?</strong>

Because string literals are stored in the read-only area of memory, while the notes variable, since initialised, is stored in the read-write region. If declared and initialised in a function, then it is stored in the stack, else most likely in the initialised data segment.
<pre class="prettyprint">*(notes[0]) = 'W';</pre>
Notes[0] → returns a char not an address

The unary operator expects an address, so this would break.

<strong>Why will the above <span style="text-decoration: underline;">not </span>work ?</strong>
<pre class="prettyprint">*(&amp;notes[0]) = 'W';</pre>
<strong>Why will the above work?</strong>

Notes[0] → returns a char not an address

&amp;notes[0] → returns the memory location (address) of the char at index 0

Since the indirection operator expects and gets an address, this would work.
<pre class="prettyprint">Wvery good boy does fine</pre>
<h2>The “Int”</h2>
<pre class="prettyprint">int num = 4;</pre>
<strong>Where does num variable live ?</strong>

If declared in a function → <span style="text-decoration: underline;">stack</span>

If declared outside a function → global → <span style="text-decoration: underline;">data segment</span>
<h3>Pointer variable to an integer</h3>
<pre class="prettyprint">int *numptr = #</pre>
<h3>Array of integers</h3>
<pre class="prettyprint">int var[5] = {1, 2, 3, 4};</pre>
<strong>Does each integer in the var array live 2 or 4 byte blocks away from each other ?</strong>

Let’s test this, shall we….
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {

int var[5] = {1, 2, 3, 4};
int * address_of_first_int = &amp;var[0];
for(int i = 0; i &lt; 5; i++){
    
    printf("Address at &lt;%d&gt; = &lt;%p&gt;; &lt;%d * %li&gt; bytes from the first int address &lt;%p&gt;\n", *(var + i), &amp;var[i],i, sizeof(int), (address_of_first_int + i));
}
    return 0;

}
Address at &lt;1&gt; = &lt;0x7ffe1d81e020&gt;; &lt;0 * 4&gt; bytes from the first int address &lt;0x7ffe1d81e020&gt;
Address at &lt;2&gt; = &lt;0x7ffe1d81e024&gt;; &lt;1 * 4&gt; bytes from the first int address &lt;0x7ffe1d81e024&gt;
Address at &lt;3&gt; = &lt;0x7ffe1d81e028&gt;; &lt;2 * 4&gt; bytes from the first int address &lt;0x7ffe1d81e028&gt;
Address at &lt;4&gt; = &lt;0x7ffe1d81e02c&gt;; &lt;3 * 4&gt; bytes from the first int address &lt;0x7ffe1d81e02c&gt;
Address at &lt;0&gt; = &lt;0x7ffe1d81e030&gt;; &lt;4 * 4&gt; bytes from the first int address &lt;0x7ffe1d81e030&gt;</pre>
It is safe to say that the answer is yes.

<em>Read up pointer arithmetics</em>

<strong>Is an array a pointer ?</strong>

Ja und nein.depending on how it is used.

A pointer to an int array → points to the memory location of first element of the array → does not hold values of the array

An int array → holds N integers → when its identifier is assigned to a pointer, it changes to the pointer of the first element
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {

int var[5] = {1, 2, 3, 4};
int * address_of_first_int = &amp;var[0];
address_of_first_int[3] = 12;
printf("Value at %d is %d", 3, var[3]);
    return 0; 

}</pre>
<strong>Why does the above work though ?</strong>

According to a stack overflow response, the symbol [] works with pointers. The integer within the symbol is used as the offset value from the first element of the array and the value residing is returned. This indicates that the “var” variable has to be converted to a pointer, before a value at a specific index can be set or returned.
<pre class="prettyprint">int *ptr = var;
int *secondptr = &amp;var[0];</pre>
<strong>What is the difference between the two pointers ?</strong>

Nada = Nothing = Nichts
<pre class="prettyprint">const int ARRAY_SIZE = 5;
int(*wholeptr)[ARRAY_SIZE] = &amp;var;</pre>
<strong>WTH is that ????</strong>

I fell into this randomly in the GeeksforGeeks blog and I thought it would also be nice here :D. It is a pointer to an array. I think I would need to create another blog post for this alone because I honestly do not get it.
<pre class="prettyprint">int *fiveintptr[ARRAY_SIZE];
for (int i = 0; i &lt; ARRAY_SIZE; i++)
    {
        /* code */
        fiveintptr[i] = &amp;var[i];
    }</pre>
<strong>Before the loop, where do each pointer in the fiveintptr pointer array point to ?</strong>

The fiveintptr variable is an array of pointers with each pointer expected to point to an int type. But since each pointer isn't assigned a value / address, it holds garbage values.
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
const int ARRAY_SIZE = 5;
int main() {

int var[5] = {1, 2, 3, 4};
int *fiveintptr[ARRAY_SIZE];
for (int i = 0; i &lt; ARRAY_SIZE; i++)
    {
        /* code */
        printf("The value pointed to by the pointer at index %d is %p\n", i,  fiveintptr[i]);
    }
    
    puts("----------------------------------------------\n");
    for (int i = 0; i &lt; ARRAY_SIZE; i++)
    {
        /* code */
        fiveintptr[i] = &amp;var[i];
        printf("The value pointed to by the pointer at index %d is %p\n", i,  fiveintptr[i]);
    }

    
    return 0; 

}
The value pointed to by the pointer at index 0 is (nil)
The value pointed to by the pointer at index 1 is (nil)
The value pointed to by the pointer at index 2 is (nil)
The value pointed to by the pointer at index 3 is 0x756e6547
The value pointed to by the pointer at index 4 is 0x9
----------------------------------------------

The value pointed to by the pointer at index 0 is 0x7ffd70e07df0
The value pointed to by the pointer at index 1 is 0x7ffd70e07df4
The value pointed to by the pointer at index 2 is 0x7ffd70e07df8
The value pointed to by the pointer at index 3 is 0x7ffd70e07dfc
The value pointed to by the pointer at index 4 is 0x7ffd70e07e00</pre>
<pre class="prettyprint">*fiveintptr[4] = 25;</pre>
<strong>Why would it work?</strong>

Fiveintptr → array of pointer

Fiveintptr[4] ---&gt; a pointer

*pointer → dereferencing a pointer → value at given address / pointer

*fiveintptr[4] → value living at an address of 3rd element of the var int array

= → basic assignment operator

// valid operation
<h2>The array of strings</h2>
<pre class="prettyprint">char top5femalartists[5][20] = {
        "beyonce",
        "jessie j",
        "christina aguilera",
        "maria carey",
        "mary j blige"
};</pre>
<strong>Do you agree with my list ?</strong>

yesssss!

<strong>What do the 5 and 20 mean ?</strong>

5 → number of char arrays that can be stored here

20 → number of characters that can be stored in each char array

<strong>What happens when a string like "beyonce" is shorter than 20?</strong>

The remaining bytes are either empty or filled up with jargon. For example…
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
int main() {

 char person[20] = "beyonce";
 printf("Value at 6 %c &lt;&gt;\n", person[6]);
 printf("Value at 7 %c&lt;&gt;\n", person[7]);
printf("Value at 8 %c&lt;&gt;\n", person[8]);
    return 0; 

}
Value at 6 e &lt;&gt;
Value at 7 &lt;&gt;
Value at 8 &lt;&gt;</pre>
<pre class="prettyprint">top5femalartists[1] = "jennifer hudson";</pre>
<strong>Why would the above expression not work ?</strong>

error: assignment to expression with array type

Because they are not identical. “Beyonce” is an array of chars ( 20 ), while "jennifer hudson" is stored in read-only memory. They are of different types.
<pre class="prettyprint">char *top5maleartist[5] = {
        "bruno mars",
        "michael jackson"
};</pre>
<strong>What does this look like ?</strong>

An array of pointers, each pointing to string literals.
<pre class="prettyprint">top5maleartist[0] = "DO of exo";</pre>
<strong>Why did the above work ?</strong>

You simple rebound the pointer to another string literal
<pre class="prettyprint">top5maleartist[0][1] = 'd';</pre>
<strong>Why wouldn't the above work ? </strong>

You are trying to modify the second character of the string literal pointed by the first pointer. Remember this value type is treated as read-only, which is said to have an “undefined” behaviour.

<em>Got the last part from stack overflow :D</em>

<strong>In what way could I make this modifiable ?</strong>

Array of chars.
<pre class="prettyprint">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
int main() {


char * top5maleartist[3];
char ch_arr[3][20] = {
                        "bruno mars",
        "michael jackson"
                     };
                     
for(int i = 0; i &lt; 3; i++){
    
    top5maleartist[i] = &amp;ch_arr[i][0];
}

*(top5maleartist[0] + 1) = 'd';
printf("Value of %s\n", (top5maleartist[0]));
    return 0; 

}
Run.....
Value of bduno mars</pre>
<ol>
 	<li>Create an array of pointers containing 3 pointers</li>
 	<li>Create an array of an array of characters</li>
 	<li>Set each pointer to the address of the first character of each char list</li>
</ol>
Top5maleartist[0] → pointer to ch_arr[0][0]

Top5maleartist[0] + 1 → shift by char characters * 1 → &amp;ch_arr[0][1]

*(Top5maleartist[0] + 1 ) → *(&amp;ch_arr[0][1]) → dereferencing

<strong>What happens to the string literal “bruno mars”?</strong>

I dunno.. .seriously.
<h2>The double pointer</h2>
<pre class="prettyprint">int num = 3;
int  *numptr = #
int **doubleptr = &amp;numptr;
printf("%d", **doubleptr);</pre>
<strong>What value does it dereference ?</strong>

*doubleptr → &amp;num

**doubleptr → *(&amp;num) → 3
<pre class="prettyprint">printf("%d\n", *numptr);
printf("%d\n", **doubleptr);
printf("%p\n", *doubleptr);</pre>
<strong>What gets logged ?</strong>

3

3

0x7fff685046f4
<h2>Author Notes</h2>
This is most likely not the cleanest implementation, just a heads up.
<h2>Links</h2>
<ol>
 	<li><a href="https://craftofcoding.wordpress.com/2015/12/07/memory-in-c-the-stack-the-heap-and-static/">MEMORY IN C – THE STACK, THE HEAP, AND STATIC</a></li>
 	<li><a href="https://gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html">Memory : Stack vs Heap</a></li>
 	<li><a href="https://www.sciencedirect.com/topics/engineering/stack-memory">Stack Memory Operations</a></li>
 	<li><a href="https://stackoverflow.com/questions/2308751/what-is-a-memory-heap">What is a Memory Heap?</a></li>
 	<li><a href="https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/">Pointers in C and C++ | Set 1 (Introduction, Arithmetic and Array)</a></li>
 	<li><a href="https://www.geeksforgeeks.org/memory-layout-of-c-program/">Memory Layout of C Programs</a></li>
 	<li><a href="https://denniskubes.com/2012/08/17/basics-of-memory-addresses-in-c/">Basics of Memory Addresses in C</a></li>
 	<li><a href="https://computer.howstuffworks.com/c23.htm">Memory addresses wonderfully explained</a></li>
 	<li><a href="https://www.tutorialspoint.com/cprogramming/c_data_types.htm">C - Data Types</a></li>
 	<li><a href="http://www.cs.ecu.edu/karl/3300/spr14/Notes/C/Memory/memory.html">The Memory and Memory Addresses</a></li>
 	<li><a href="https://www.geeksforgeeks.org/whats-difference-between-char-s-and-char-s-in-c/">What’s difference between char s[] and char *s in C?</a></li>
 	<li><a href="https://overiq.com/c-programming-101/array-of-strings-in-c/">Array of Strings in C</a></li>
 	<li><a href="https://stackoverflow.com/questions/20347170/char-array-and-char-array">char *array and char array[]</a></li>
 	<li><a href="https://www.geeksforgeeks.org/pointer-array-array-pointer/">Array pointers</a></li>
 	<li><a href="https://www.geeksforgeeks.org/pointer-vs-array-in-c/?ref=rp">Pointer vs Array in C</a></li>
 	<li><a href="https://www.computerhope.com/jargon/a/array-of-pointers.htm">Array of pointers</a></li>
 	<li><a href="https://overiq.com/c-programming-101/array-of-pointers-to-strings-in-c/">Array of pointers to strings</a></li>
 	<li><a href="https://www.geeksforgeeks.org/double-pointer-pointer-pointer-c/">Double pointers</a></li>
 	<li><a href="https://codeforwin.org/2015/05/list-of-all-format-specifiers-in-c-programming.html">%li</a></li>
 	<li><a href="https://www.geeksforgeeks.org/size_t-data-type-c-language/">Size_int</a></li>
 	<li><a href="https://medium.com/@nonuruzun/where-global-variables-are-stored-e1a8b7e90275">Where global variables are stored?</a></li>
 	<li><a href="https://stackoverflow.com/questions/52463689/rationale-behind-code-segment-and-data-segment">Rationale behind code segment and data segment</a></li>
 	<li><a href="https://www.uninformativ.de/blog/postings/2015-10-25/0/POSTING-en.html">Storage of global and static variables in C</a></li>
 	<li><a href="https://en.wikipedia.org/wiki/Executable">Executable</a></li>
 	<li><a href="https://en.wikipedia.org/wiki/Code_segment">Code segment</a></li>
 	<li><a href="https://en.wikipedia.org/wiki/Data_segment">Data segment</a></li>
 	<li><a href="https://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/">C Strings (Arrays vs. Pointers)</a></li>
 	<li><a href="https://stackoverflow.com/questions/5033627/static-variable-inside-of-a-function-in-c">Static variable inside of a function in C</a></li>
 	<li><a href="https://www.tutorialspoint.com/where-are-static-variables-stored-in-c-cplusplus">Where are static variables stored in C/C++?</a></li>
 	<li><a href="https://stackoverflow.com/questions/47301556/difference-between-stack-segment-and-uninitialized-data-segment">difference between stack segment and uninitialized data segment</a></li>
 	<li><a href="https://stackoverflow.com/questions/3113668/location-of-pointers-and-global-variables-in-c">Location of pointers and global variables in C</a></li>
 	<li><a href="https://www.tutorialcup.com/cprogramming/array-memory-allocation.htm">Array Memory Allocation in C Programming</a></li>
 	<li><a href="https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer">Is an array name a pointer?</a></li>
 	<li><a href="https://www.geeksforgeeks.org/pointer-array-array-pointer/">Pointer to an Array | Array Pointer</a></li>
 	<li><a href="https://www.geeksforgeeks.org/difference-between-pointer-to-an-array-and-array-of-pointers/">Difference between pointer to an array and array of pointers</a></li>
 	<li><a href="https://stackoverflow.com/questions/2589949/string-literals-where-do-they-go">String literals: Where do they go?</a></li>
</ol>