Lecture 4 - Memory
Hexadecimals
- digital images like all computer information, made up of code, ie pixels
- images are made by printing out horizontal line by line, called scan lines
- the colour of each pixel is defined by a methods, one being RGB, that is the strength of Red, Green and Blue present in image.
- these three value’s each range from 0 to 255
- can also be represented in a hexadecimal system, with 6 total values, where 3 pairs of values each represent one of the colours
- this is the system used for html and css
- a hexidecimal system, or base sixteen, uses a 15 numeral system (decimal = 10, binary = 2) across two bits of information
- 0 1 2 3 4 5 6 7 8 9 A B C D E F are the value used
- in the right digit is 16^0, which equals 1, so the right digit deals with single value
- in the left digit is 16^0, which equals 1, so the left digit deals with multiples of 16
For example
- 5D would represent 93 (16X5 + 13)
- C4 would equal 196 (16X12 + 4)
Memory addresses
- in previous lectures we’ve counted memory bytes as decimal
- convention is actually to use hexidecimal
- So what number follows the F
- the 16? No, because using the above system we know that 10 represents 16 in hexidecimal
- so 10? well that becomes a little confusing for humans, could presume it is a decimal system
- the method that has been established is to put a 0x to distinguish a value as hexadecimal
- so the value which follows 0xF is 0x10
Pointers
- When we initialise an int in c (remember an int automatically uses 4 bytes aka 32 bits of memory), a somewhat random point in the RAM is allocated to this variable
- This position will be represented by a hexadecimal value, which is its own variable
- So we are initialising a value for the variable (decimal) and also the location for this value (the other variable, hexidecimal, representing the specific byte in which value is stored)
- reminder, a double && can create a conditional where multiple boolean expression must be true
- a single & means the address of, so &variable will give you the hexidecimal address in computers memory of a variable, rather than its decimal value
- if you want to store an address of a value, you need to use an *
- ie int *variable = hexidecimal address would be used for an int address
- so a pointer is a variable that points an address of another variable
- pointers are now automatically 8 bytes (64-bit), regardless to the data type the point to, like a char of 1 byte or an int of 4 bytes because computers are so powerful now, they are able and need to count up huge numbers, which 64-bit is more than capable of handling
A second use for asterix operator
The asterix can also be used when we want to not use the address of a variable, but if we have an address and want to see what the variable it is pointing to
- in this example, the integer at *p returns 50, not the address
- another note for pointers, when to call the pointer of a variable, we use %p, rather than %i, %c, etc.
The String datatype
- so we learnt that the string data type we have been using is actually an invention of the cs50.h library and not the data type used for a ‘string’ normally.
- it is actually char *
- given what we just learned about the asterix operator tells us that a string is really a pointer to the beginning of a string, and that string ends when it reaches the NUL character
- so the variable s equals HI!, however *s equals it’s hexadecimal address (0x123) for %p and the first value of array at %i
- we now have an equivalent to s[0], s[1], s[2], etc.
- that is *s, *(s+1), *(s+2)
- compiler automatically knows that we need to move up one piece of data, so plus 1 works for chars, ints, floats which are also different byte-sizes
- This explains why string compare doesn’t work as we expect, because we are actually comparing the address of the beginning point of two variables, which can’t be the same
malloc and free
Copying variables - if we copy one string to another, we aren’t actually creating another copy, we are just copying over the address. So each variable will point to the same data in memory
- bin order to do this correctly, we first need to allocate the required space using malloc
- remember we also need to add space for the NUL character, not just all the values of string
- it is best to add space dynamically, ie using strlen command
- once space has been allocated, we can use a for loop or strcpy command form string.h library to copy string
- once we have completed our algorithm we must always call free to empty the memory space used and to prevent any data leaks
The valgrind command can be used in the Command Line interface when running program to analyse memory use of program and detect errors
As i have noticed in debugger, before you initialise values to have a value in program, when initialised they sometimes contain a random number. this is called a garbage value.
- this can happen if there are leftover values that were previously allocated to memory but not cleared by computer
- and you then get access to that block of memory but don’t populate it with your own value
Copying values always requires some temporary space to hold one of the variables
Scope
In previous weeks we covered the concept of scope, because sometimes arrays have only been limited to the function in which they were called or initialised
- memory is used in a convential way
- not random
- uses different parts of memory for different purposes
- first up is machine code, all zeroes and one used when program compiled and run
- here we see global variables have their own area which is separate to the rest of the memory used by program, variables outside of main
- then there is heap, when we use malloc, this is what memory we use
- and stack, so we have been using stack heavily in our programs so far
- buffer overflow is when we run out room in the bottom area, either by filling the stack or heap, which specify the exact cause of overflow
Swapping variable values
- so when passing two variables into another function within main, we are actually making two additional copies of the variables and only using those within the second function, so any changes we make do not impace the originals
- in order to swap two variables in another, instead of copying the variables, we can copy the addresses, and therefore be directly changing the original copies, seen in below code
scanf, the true get_string/int/float
- when we’ve been using get_*** its been a part of cs50.h library also
- the conventional way to get a value is using scanf
- from stdio.h library
- this scans the user’s computer keystrokes and stores in memory, have to give it at the address of the variable (&variable)
- when doing it for char *s, s is already an address so we dont need the &
- scanf is problematic if we don’t dynamically allocate memory to our variables
- incorrect memory allocation can lead to segmentation fault
FILE INPUT / OUTPUT
within see we can use pointers to files and the FILE data type to call files within program, allowing us to open, print and write to files.
- we will explore in greater detail in coming weeks