 Download Download Presentation Pointers and Dynamic Memory

# Pointers and Dynamic Memory

Download Presentation ## Pointers and Dynamic Memory

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
##### Presentation Transcript

1. Pointers and Dynamic Memory

2. Memory Management • Memory management • Arrays • Dynamic memory • Dynamic arrays and pointers • Building a vector class

3. Memory Management

4. Memory Requirements code storage data storage

5. Memory Management • When a program runs memory has to be allocated for its processes and its variables • That is, working memory, or RAM • There needs to be a system for efficiently allocating such memory • We will just consider how memory is allocated to program data (variables)

6. RAM • We can consider Random Access Memory (RAM) as a long sequence of bytes • Starting with 0 • Ending with the amount of main memory (-1) • RAM is addressable and supports random access • That is, we can go to byte 2,335,712 without having to visit all the preceding bytes

7. RAM Illustrated Consider a computer with 1GB * of RAM *1 GB = 1,073,741,824 bytes This is a fairly abstract illustration (so ignores a variety of issues)

8. Goals • As much as possible we would like to satisfy three goals when allocating memory • Time efficiency • That is, we should be able to quickly find sufficient memory to store a variable • Space efficiency • We don't want to waste memory • Low overhead • We don't want a large amount of administration

9. Stack Memory • There is a very simple way of organizing memory that meets these goals • Assign memory locations to variables in sequence • With no gaps • Once a variable is no longer required release the memory, allowing it to be over-written • We will call this organization the stack • Or automatic memory • Although the stack cannot be used for everything

10. Stack Memory – Simple Example Let's look at a simple example of allocating memory on a stack as described preciously int x = 12; x = x * 3; double d = 23.567; 36 23.567 12 Why start at byte 3600? No reason, it's just an arbitrary value Notice that this example ignores all sorts of complicating issues, functions, reference variables and so on …

11. Stack and Functions • Let's look at a more complex example of allocating memory • That includes a main function and two other function calls • To make the example a bit simpler I will stop showing actual byte values • And just use coloured boxes to represent the memory allocated to variables

12. Another Example double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi; } int main(){ int r = 3; double area = circleArea(r); double square(double x){ return x * x; } main memory x 3 3 3.1415 3 r radius pi square's memory start of circleArea's memory

13. Another Example double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi; } int main(){ int r = 3; double area = circleArea(r); double square(double x){ return x * x; } main memory 3 3 3.1415 9 r radius pi sq_r start of circleArea's memory

14. Another Example double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi; } int main(){ int r = 3; double area = circleArea(r); double square(double x){ return x * x; } main memory 3 28.274 r area

15. Stack Memory • In stack memory variables for a function are allocated the next bytes in main memory • From the last variable allocated space by the same program • Once a function ends its memory is released • Remember that a function's variables only exist while the function is executing • So the memory previously allocated to a completed function can be re-used

16. Reference Parameters • Some functions have reference parameters • There are two common reasons for doing this • Efficiency • int sum(const vector<int> & v) • Sums the contents of the vector • And because we want the changes made to the variable to persist after the function • void square_all(vector <int> & v) • Squares each value in a vector

17. Stack Problems • There is one big issue with stack memory • Because memory is allocated in sequence it is not possible to change the byte size of a variable • Strings and vectors frequently change size • It is more correct to say that a string variable may refer to strings of different sizes • A vector can change size by using its push_back method

18. Changing a Vector's Size void insert_next(int n, vector <int> & v){ for(inti=0; i < n; i++) v.push_back(i + v.size() + 1); } } int main(){ vector <int> vec(3); v = 1; v = 2; v = 3; double vid = 2.397; insert_next(3, vec); main memory 1 2 3 2.397 vec vid* *very important double 

19. Changing a Vector's Size void insert_next(vector <int> & v, int n){ for(inti=0; i < n; i++) v.push_back(i + v.size() + 1); } } int main(){ vector <int> vec(3); v = 1; v = 2; v = 3; double vid = 2.397; insert_next(vec, 3); This is a problem, we've just corrupted the first 4 bytes of vid main memory 1 2 3 4 2.397 3 o vec vid* v * n i *very important double  *v is a reference to vec, it actually contains the byte address of vec

20. Types Of Memory • It turns out you can divide memory into three broad categories • Static • Automatic • Dynamic • These types of memory are typically used for different sorts of program data • Although C++ gives programmers choice over which type of memory to use

21. Storage code storage data storage static dynamic automatic

22. Static Storage • Statically stored variables last for the lifetime of a program • The number of static variables does not change as a program runs • So no special system is required to maintain them • Static storage is used for global constants • And other things …

23. Automatic Storage • Function variables and parameters use automatic storage by default • Automatic variables are typically managed on a stack as we have been discussing • The stack is an allocated area of memory that grows and shrinks as functions are called • Memory is allocated sequentially (without gaps)

24. Functions and Memory • A variable defined in a function block only persists for the lifetime of that function call • Unless it is declared as static • Consider what memory might be allocated when a function is running • Memory required for the function’s data and only required during the function call • Memory that is to persist beyond the lifetime of the function – we can't use the stack for this!

25. Arrays A Digression From Memory

26. Arrays • Before looking at dynamic memory let's look at a basic data structure – the array • Arrays are used to store multiple values of the same type, much as vectors do • Except that arrays are much more basic data structures without methods (such as size) • Arrays are indexed and we can either refer to individual elements or the entire array • Much like vectors

27. What Is An Array? • An array variable is a collection of other variables • You can think of an array as something that contains variables • This is important because an integer array is not an integer, it is a collectionof integers • The items stored in an array (elements) are stored sequentially in main memory • Just like variables on the stack

28. Declaring Arrays • An array is declared with a type, and []s to indicate that the variable is an array • The type declares the type of the array elements name of the array size of the array intmyArray type of the data stored in the array brackets declare that the variable is an array

29. Array Indexing • The elements of the array are accessed using an index • The indexes are addresses of the elements • The first element always has an index of 0 • The last index is always array size – 1 • Array indexes follow the name of the array and are enclosed in []s • Individual array elements are used in exactly the same way as variables

30. Using an Array • doublearr;// array of 4 doubles • arr = 1.23; //assign 1st element • arr = 2.14; //assign 4th element • double x = 0; • x = arr; //access 4th element 1.23 2.14 0 2.14 x the table represents main memory, each cell is an 8 byte double

31. Initializing Arrays • Array elements have to be given values individually • This is often done in a loop • There is a special shorthand notation for initializing arrays when they are declared • intarr[] = {1, 3, 7, 9}; • This shorthand notation is only allowed on the same line as the declaration

32. Array Size • An array's size must be specified when it is declared • It must be a literal (i.e. a number) or • A constant • It can't be given using a variable • An array's size cannot change during the life of a program • Arrays can therefore be allocated space in automatic memory as their size cannot change

33. Arrays and Vectors • Arrays are not vectors, and are not classes • Arrays do not have methods • Like size or push_back • The size of an array has to be recorded in a separate variable, and may not be changed • An array is essentially a way of referring to a collection of values of the same type • Its elements

34. Arrays and Loops • Arrays are often processed using loops • Allowing each element to be accessed in turn • The loop control variable is used as an index into the array • The loop ends once the array has been processed • Often when the loop control variable is equal to the size of the array • This is very similar to how we have iterated through the elements of a vector

35. For Loops // Assume an int array named arr, // with a constant called ARR_SIZE // The loop prints the contents of arr for (inti = 0; i < ARR_SIZE; i++){ cout << arr[i] << endl; } The condition is i < ARR_SIZE because the last legal index is ARR_SIZE – 1 Assumes the existence of a constant called ARR_SIZE, e.g. const int ARR_SIZE = 10;

36. While Loops // Assume an int array named arr, // with a constant called ARR_SIZE // The loop prints the contents of arr inti = 0; while (i < ARR_SIZE){ cout << arr[i] << endl; i++; } A very similar loop to the for loop, we must not forget to increment the index, i

37. Size as a Constant • It is much better to define array size as a constant than to use a literal value (like 10) • If the programmer wants to change the array size this only needs to be done once • Use the constant whenever the array size is referenced, and • Avoid using magic numbers!

38. Index Out of Bounds • What happens if a program attempts to access a non-legal index? • A run-time error occurs, either • An illegal attempt to access a memory location has been made (… stack is corrupted …) , or • Something less predictable • Always check that an index is legal • Between 0 and array size – 1

39. Arrays And Functions Array digression continues …

40. Array and Functions • Arrays can be passed to functions as parameters • Parameter lists can include arrays • The array type, and the fact that it is an array must be specified in the parameter list • An array is specified just like any declaration • Here is the header for an array sum function • intsumArray(intarr[], intsz){

41. Sum Function // Sums the array, returning the sum intsumArray(intarr[], intsz){ int sum = 0; for (inti = 0; i < sz; i++){ sum += arr[i]; } return sum; } sz is used to specify the size of the array To use this function give it the appropriate arguments x = sumArrray(myArr, ARR_SIZE);

42. Searching Arrays • A common array task is to search an array for a particular value int search(intarr[], intsz, int x){ int result = -1; for (inti = 0; i < sz; i++){ if (arr[i] == x) returni; } return result; } Returns the index of the target as soon as it is found Returns -1 (an invalid index) if the target isn't found

43. Aside – Using Arrays • Make sure that you distinguish between an array and its contents • intarr; • arr is the entire array • arr is one element of the array • The array is a sequence of integers, one element is an integer • They are not interchangeable

44. Is the Array Full? • It is often important to know how much of an array is used • Unassigned elements shouldn't be processed • e.g. summing or calculating the average of an array • Consider what input a function requires • Array, and its maximum size, or • Array, and current size ,or • i.e. the number of elements actually used • Array, maximum size, and current size

45. Returning Arrays • Arrays can be returned from a function • However the obvious way of specifying the return type is illegal • int[] getAnArray() { … • In addition, returning an array raises the question of how big the array is • Before continuing this we need to know more about how arrays really work This does not work!

46. Arrays And Memory What is an array really?

47. Changing Arrays • What happens if you pass an array to a function that changes the array parameter? voiddoubleArray(intarr[], intsz){ for (inti = 0; i < sz; i++){ arr[i] = arr[i] * 2; } } Notice that this is not pass by reference

48. Array Parameters intmain() { doublearr[] = {1, 2, 3}; printArray(arr, ARR_SIZE); cout << "Running: void doubleArray"; cout << "(double arr[], intsz);" << endl; doubleArray(arr, ARR_SIZE); printArray(arr, ARR_SIZE); return 0; } What has happened? The array passed to the function has changed. This does not happen with other pass-by-value parameters

49. What's an Array? • To understand what is going on in the previous example we need to know more • It's easy to think of an array as a container, like a bookcase or a filing cabinet • But these are structures in their own right • An array is just a collection of values • All of the same type, and • Stored in sequence in main memory • It is not an object of a class like a vector

50. More About Arrays • An array is a sequence of bytes in main memory reserved for the array contents • e.g. intarr; • Reserves 40 contiguous bytes • An int is 4 bytes, 4 * 10 = 40 • Each element can be referenced using indexes • The variable arr is just the address of, or a pointer to the first array element • Contains the address of the first array element