CS50x : Week 4: Memory

In Week 4 we were introduced to various concepts revolving around how memory is used and managed in C.

Memory Structure:

Memory is organized as 2 Dimensional Arrays. Every memory location contains an address. Generally hexadecimal numbers are used to represent memory address. A hexadecimal number is represented with a 0x prefixed to it, for example: 0x123.

Pointer:

A pointer is a variable that contains memory address of a some value.

It is denoted using the star * operator.

int n = 50;

int *p = &n;

Here pointer p stores the address of n, & ampersand is an opreator that returns the address of whatever varaible comes after it.

Pointers are a very powerful tool to manage variables, manipulate them, and manage the memory inside a computer.

Strings:

Now that we know what a pointer is, we can now understand how a string is declared in native C. Until now we used the CS50's implementation of a string which was string s; but now we learn that beneath that abstraction it actually is: char *s;

That is the pointer s points to the memory address of the first character of the string.

Then we learn how pointer arithmetic was used to implement the syntax: s[0], s[1], s[2], where the underlying syntax actually was: *s, *(s + 1), *(s + 2) and so on.....

Next we leant how string comparsion works and why s = t can't work because we are comparing the addresses of two strings rather than the string itself so to compare two strings we need to use the srtcmp function from string.h library.

Copying strings using s = t won't work as it will result in both pointers pointing to the same block of code.

malloc and free:

malloc and free are functions available in the stdlib.h library that allow us to allocate or deallocate memory to a particular variable.

syntax: malloc(size); malloc returns a void pointer of the beginning of the memory block. Thus malloc can be used with a pointer of any type.

example: char *t = malloc(10); this will allocate 10 bytes to the string t.

free is used to free the memory allocated using the malloc function. It is important and a good practice to always free the memory allocated using malloc after there is no further use for the memory.

syntac: free(variable_name); example: free(t);

Valgrind is a program that can be used to analyze the memory use of another program, It can be used to debug memory leaks, or segmentation faults.

memory leak happens when we don't free the memory used by out program after execution, a segmentation fault occurs when we end up touching a part of the memory that we aren't supposed to during the execution of a program.

Garbage Values:

It is possible that the memory we allocate to a variable in our program may be previously used by another program or operating system functions, thus it may not be initatlised to 0 and may include random values. these random values are called garbage values. It is important to intialise the values of our memory to 0 before working on it to avoid garbage values.

Next we learnt how to implement a simple swap algorithm by using a function.

We run into a problem as when using a function to implement swap without pointers we use pass by value thus making duplicate copies of original data and due to thes duplicates being in a different scope from the main function they are destroyed once the swap function has been executed. Thus we use pointers to implement a swap function thus utilizing pass by reference which insures the original values are passed onto the function and the function returns the swapped values.

Overflow:

A heap overflow is when you overflow the heap, touching areas of memory you are not supposed to.

A stack overflow is when too many functions are called, overflowing the amount of memory available.

Both of these are considered buffer overflows. A buffer is a chunk of memory.

scanf:

next we learnt how to use scanf to input values into a program using pointers.

Until now we used functions like get_int, get_string from the CS50 library to accept different values but now with the understanding of pointers we can use scanf which is available in the stdio.h library to accept inputs:

Here is an implementation of get_int:

#include <stdio.h>

int main(void)
{
    int x;
    printf("x: ");
    scanf("%i", &x);
    printf("x: %i\n", x);
}

as we can see we used ampersand operator to refer to the address of the variable x.

File I/O:

we can use different functions such as fopen, fclose, fprintf, fscanf, fread to perform various operations on a file inside a program.

Summing Up:

In this lesson, we learned about pointers that provide us with the ability to access and manipulate data at specific memory locations. Specifically, we delved into…

  • Hexadecimal

  • Memory

  • Pointers

  • Strings

  • Pointer Arithmetic

  • String Comparison

  • Copying

  • malloc and Valgrind

  • Garbage values

  • Swapping

  • Overflow

  • scanf

  • File I/O