# CS50 Week 4: Memory

Pointers, pointers, pointers!

• Base 16, hexadecimal base (0 - f) Remember `int`s are four byes.
• One hexadecimal digit is equivalent to four binary digits
• If you are using hexadecimal, the convention is to prefix every value with `0x`
• So... the `hex` color values are just the hexadecimal RGB values (and in a different format)!
• In C memory, values are stored in hexadecimal.

• A pointer is a variable that contains the address of some other value.
• `&` "the address of" operator (we use it every time we want to check what address a variable is stored at)
• `*` "go to the address of" operator(for telling your program to look inside a particular memory address). Also known as the dereferencing operator.
• `%p` - aka pointer - for the placeholder value to be interpreted as hexadecimal
``int n = 50;prinf("%p\n", &n)// returns eg: 0x123456789// this will just print out 50prinf("%i\n", *&n)``

And if you want to store the address of some variable inside another variable, you would use a pointer (an `int star` variable):

``int n = 50;int *p = &n;// and to print the value stored at p// get the value at the addressprinf("%i\n", *p)``
• If you are getting the address of something, you must store it in a pointer (*).
• Pointers have 64 bits (the equivalent of a `long`)

A string is defined as back-to-back-to-back characters (one byte away, since a `char` take one byte of space in C).

• 🤯 strings are just pointers pointing to the first character in the string
• the null terminating character signifies the end
``int n = 50;int *p = &n;string s = "EMMA";char *s = "EMMA";``
``typedef char *string;``

🔈 NEW STRING DEFINITION: A string is a variable that contains the address of a character, aka `char *`

``char *s = "EMMA";printf("%p\n", s); // the address of the charprintf("%p\n, &s); // the address of the 1st char (same as ^)printf("%c\n", *s); // prints "E"// pointer arithmeticprintf("%c\n", *(s+1)); // prints "M"``
• when you're comparing two strings, if you just compare them like this `s == t` you are comparing their addresses in the memory, meaning these two strings will never be the same! (that's why you need to use `strcmp()` instead)
``// changing one, will change the other char *s = get_string("s: ");    char *t = s;    t = toupper(t);``

``// copying a string in c// without using strcopy()#include <cs50.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void){    char *s = get_string("s: ");    char *t = malloc(strlen(s) + 1);	// when allocating memory always check that malloc	// is giving you back a valid memory address and not NULL    if (t == NULL)    {        return 1;    }	// we need to include \0 that's why n + 1	// or i <= n    for (int i = 0, n = strlen(s); i < n + 1; i++)    {        t[i] = s[i];    }    if (strlen(t) > 0)    {        t = toupper(t);    }    printf("s: %s\n", s);    printf("t: %s\n", t);    free(t);}``

`malloc()` - memory allocate `free()` - freeing the memory previously allocated `strcpy(str1, str2)` - for copying strings

**Anytime you use `malloc()`, you must use `free()` afterward.

• `valgrind` debugging tool helps you debug invalid reads, invalid writes, segmentation faults, or memory leaks (aka when you've allocated more memory than you have freed)
• to run it: `valgrind ./hi`
• You can preface it with `cs50` to get a more helpful output.

🤔 What is a garbage value?

• Anytime that you don't initialize the value of a variable
• If you try to dereference and uninitialized variable, your program might crash.
• Ergo, you should always initialize values before touching them (read/write) in any way 👍
``````
int *x = malloc(10 * sizeof(int));
// allocate enough memory for 10 integers, and then
// store the address of that chunk of memory
// in a pointer called x.
``````

🤔 What is a buffer overflow?

When you are overflowing the allocated memory (either stack overflow or heap overflow)

In terms of standard order (you can imagine it going top to bottom):

• machine code (the 0s and 1s representing your program)
• globals (global variables)
• heap (this where you can allocate/free the memory from/to with malloc) - can lead to heap overflow
• stack - the memory for your functions, variables, parameters (can lead to stack overflow)
``// swapping values in C// note you must use pointers!// otherwise only params a, b will be changed// but the original x, y will remain as they were// you wouldn't need pointers if you did all// the swapping inside main#include <stdio.h>void swap(int *a, int *b);int main(void){    int x = 1;    int y = 2;    printf("x is %i, y is %i\n", x, y);    swap(&x, &y);    printf("x is %i, y is %i\n", x, y);}void swap(int *a, int *b){    int tmp = *a;    *a = *b;    *b = tmp;}// vs naive, old version of swap// that doesn't change x, yvoid swap(int a, int b){    int tmp = a;    a = b;    b = tmp;}``

Meaning! If you use the stack's memory you save yourself the trouble of having to do `malloc()` AND `free()` 🤯

``	char s;	// vs	char *s = malloc(4);``

All the CS50 `get` libraries (`get_int`, `get_string`), were there to help you with pointers. Equivalent of `get_int`:

``int x;prinf("x: ");scanf("%i", &x);prinf("x: %i\n", x);``

for `get_string`:

``char s;prinf("s: ");scanf("%s", s);prinf("s: %s\n", s);``

``	// C does come with a pointer type FILE	// that... 🥁 points to a file	FILE *file = fopen("phonebook.csv", "a");	// always check for NULL    if (file == NULL)    {        return 1;    }``

This is how you define a `BYTE`:

``	typedef uint8_t BYTE;``

🤔 How do you recognize a jpg file?

The first three bytes of any `.jpg` files are: `0xff`, `0xd8` and `0xff`.

🤔 What is a bitmap?

A map of bits 🥁

And, finally, this is how you copy a file, one byte at a time:

``#include <stdint.h>#include <stdio.h>#include <stdlib.h>typedef uint8_t BYTE;int main(int argc, char *argv[]){    // Ensure proper usage    if (argc != 3)    {        fprintf(stderr, "Usage: copy SOURCE DESTINATION\n");        return 1;    }    // open input file    FILE *source = fopen(argv, "r");    if (source == NULL)    {        printf("Could not open %s.\n", argv);        return 1;    }    // Open output file    FILE *destination = fopen(argv, "w");    if (destination == NULL)    {        fclose(source);        printf("Could not create %s.\n", argv);        return 1;    }    // Copy source to destination, one BYTE at a time    BYTE buffer;    while (fread(&buffer, sizeof(BYTE), 1, source))    {        fwrite(&buffer, sizeof(BYTE), 1, destination);    }    // Close files    fclose(source);    fclose(destination);    return 0;}``