From 61c8b81beaa26b5d36f817129275debda9e45094 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Sun, 17 Sep 2023 19:36:06 -0400 Subject: [PATCH 01/43] adding lab 4 material --- labs/04_memory_debugging/README.md | 117 +++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 labs/04_memory_debugging/README.md diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md new file mode 100644 index 0000000..fe77dfd --- /dev/null +++ b/labs/04_memory_debugging/README.md @@ -0,0 +1,117 @@ +# Lab 4 — Memory Diagrams and Memory Debugging + +## Checkpoint 1 +*estimate: 30-45 minutes* + +- Form a group of 2 members. If the number of students in the room is not divisible by 2, the graduate TA will approve a single team with 3 members. + +- Introduce yourself to your teammate. Ask them to share something about themselves (e.g. hobbies, sports, favorite music, etc.) Learn something new about each of your teammates (even if you already know them). + +- Following the conventions used in Data Structures lecture for memory diagramming, draw a picture of the stack and the heap that result from executing the statements below. Use a ‘?’ to represent uninitialized values. + +```cpp +char*** carrot; +char** broccoli; +char* tomato; +char radish = 'q'; +tomato = new char; +*tomato = 'z'; +broccoli = new char*; +*broccoli = tomato; +carrot = new char**; +*carrot = broccoli; +``` + +Show your diagram to your teammate, and ask the teammate to reverse engineer code for your diagram; at the same time, you reverse engineer code for your teammate's diagram. + +When everyone has finished writing code for the drawing, discuss your answers as a group. Are differences in the original and reverse engineered code valid alternate answers? Or was something misinterpreted? Critique each other’s diagrams. What could be improved or drawn more clearly? What statements need to be added to each example to clean up / prevent memory leaks? + +**To complete this checkpoint**, present your work to a TA/mentor. + +## Checkpoint 2 & 3: + +Checkpoints 2 and 3 focus on using a memory debugger. It is highly recommended that you thoroughly read +the instructions for Checkpoint 2 and Checkpoint 3 before starting. + +Memory debuggers will be a useful tool in many of the assignments this semester, and in C++ development +if you work with the language outside of this course. While a traditional debugger lets you step through your +code and examine variables, a memory debugger instead reports memory-related errors during execution and +can help find memory leaks after your program has terminated. The next time you see a “segmentation +fault”, or it works on your machine but not on Submitty, try running a memory debugger! + +Please download the following 4 files needed for this lab: + +## Checkpoint 2 +*estimate: 20-40 minutes* + +For Checkpoint 2 of this lab, we will revisit the final checkpoint of the first lab of this course; only this time, +we will heavily rely on dynamic memory to find the average and smallest number for a set of data from an +input file. You will use a memory debugging tool such as DrMemory or Valgrind to fix memory errors and +leaks in buggy lab4.cpp. Make sure to download the provided .txt files as well. +First take a look at the code inside the identifyMeanAndMin() function. You will notice that the syntax used +throughout the program may be a little different than what youre used to. Try and familiarize yourself with +this syntax before you start working on the assignment. What does the code *(intArray + *numElements) += readInt; do? Whats going on inside the for loop? If youre stuck on this, ask a mentor or TA for help as +soon as possible and refer back to your lecture notes on pointers and arrays. +Once youve done this, compile the program using: +```console +g++ buggy_lab4.cpp -o buggy_lab4.out -g -Wall +``` + +Try running the program normally using: ./buggy_lab4.out +You will notice that a segmentation fault occurs. Now run this program using either Valgrind or DrMemory. +If running using Valgrind, remember to use --leak-check=yes or --leak-check=full . + +Your memory debugger should give you more context as to why a segmentation fault is occurring, especially +if youve compiled with -g. To complete this checkpoint, add or modify code in the areas marked Parts 1, 2, +and 3 to resolve all memory errors and leaks. As you are working on this, be sure to also think about the +questions asked in Checkpoint 3. +It is highly recommended that you tackle one part at a time. For example, after adding a few lines of code +to part 1, you will now receive different memory errors when you recompile and run the program using your +memory debugger. Similarly, fixing all memory errors in part 2 will generate different memory errors that +should be resolved in part 3. +In part 2 of buggy lab4.cpp, the goal is to print out the contents of intArray in reverse order, while also +calculating the sum of all elements in the array and keeping track of the smallest number encountered. +Solutions that attempt to print the contents of the array in a different manner or end up with the wrong +value for the smallest number found or sum wont be accepted. +Note that: +- You are only allowed to modify or add code when asked to. This would be between the comments that +indicate parts 1, 2, and 3 inside buggy lab4.cpp. Do not modify other parts of the code or create any +helper functions. +- You are not allowed to declare new variables; the ones provided are more than enough. Hint: how do +we create memory on the heap? +- You are not allowed to use additional data structures (like arrays or vectors). + +**You will receive no credit if you do not follow the above restrictions.** + +**To receive credit for this checkpoint**: Fix buggy lab4.cpp so that it successfully prints out the average +and smallest number for a given set of data and is free of all memory errors and leaks on your local machine. +Submit buggy lab4.cpp on Submitty and verify that there are no memory errors there as well and show a +mentor or TA both results. Also explain to a mentor TA what you added or modified in the program to +resolve all memory errors. + +## Checkpoint 3 + +As you work through Checkpoint 2, try and pay close attention the analysis given by DrMemory or Valgrind +and think about the following: + +1. How does the output from your memory debugger differ when you compile your program with the -g +flag compared to when you leave it out? +2. How would you rewrite the for loop in part 2 to use the bracket [] operator instead of pointer syntax? +3. For DrMemory users, you wouldve encountered all of these errors in parts 1, 2, or 3 of Checkpoint 2: +UNITIALIZED READ +UNADDRESSABLE ACCESS +INVALID HEAP ARGUMENT +LEAK +4. What do you think each of these errors mean? +5. For Valgrind users, the errors you will have seen are: +```console +Use of uninitialised value +Invalid write +Invalid read +Conditional jump or move depends on uninitialised value(s) +Mismatched free() / delete / delete [] +? bytes in ? blocks are definitely lost in loss record ? of ? +``` + +**To receive credit for this checkpoint**, discuss your answers to these questions with a TA or mentor. From 83f2c74f1385f8c2ce188750565ce44b6d099dda Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Sun, 17 Sep 2023 19:40:29 -0400 Subject: [PATCH 02/43] adding source and txt files --- labs/04_memory_debugging/buggy_lab4.cpp | 116 ++++++++++++++++++++++++ labs/04_memory_debugging/first.txt | 4 + labs/04_memory_debugging/last.txt | 49 ++++++++++ labs/04_memory_debugging/middle.txt | 10 ++ 4 files changed, 179 insertions(+) create mode 100644 labs/04_memory_debugging/buggy_lab4.cpp create mode 100644 labs/04_memory_debugging/first.txt create mode 100644 labs/04_memory_debugging/last.txt create mode 100644 labs/04_memory_debugging/middle.txt diff --git a/labs/04_memory_debugging/buggy_lab4.cpp b/labs/04_memory_debugging/buggy_lab4.cpp new file mode 100644 index 0000000..302d8fb --- /dev/null +++ b/labs/04_memory_debugging/buggy_lab4.cpp @@ -0,0 +1,116 @@ +#include +#include + +#define MAX_ARRAY_SIZE 50 + + + +/** IMPORTANT: SOLUTIONS THAT DO NOT FOLLOW BELOW INSTRUCTIONS WILL RECEIVE NO CREDIT + * Do not add or modify code in this file UNLESS ASKED TO! + * You are NOT allowed to declare new variables; use the ones already declared. + * You are NOT allowed to create new helper functions or modify checkCorrectSmallest() +**/ + + + +/** DO NOT MODIFY THIS FUNCTION! **/ +int checkCorrectSmallest(int* smallestNum, const std::string& filename) { + if (filename == "first.txt" || filename == "middle.txt") { + if (*smallestNum != 1) {return -1;} + } + + else if (filename == "last.txt") { + if (*smallestNum != 22) {return -1;} + } + + return 1; +} + +/** A function that will identify the mean and smallest number + * in a set of data provided that there are at most 50 numbers + * in the file. + * + * @param filename: The name of a file that contains a list of numbers. + * + * Task: Add or modify code in the appropriate sections to fix memory and logic errors + * without using data structures (such as an array or vector) and without using any + * additional memory on the stack. +**/ + +void identifyMeanAndMin(const std::string& filename) { + int* numElements; + int* sum; + int* smallestNum; + float* avg; + + /** PART 1: ADD CODE BELOW **/ + + + + + /** PART 1: ADD CODE ABOVE **/ + + *numElements = 0; + *sum = 0; + + int readInt; + int* intArray = new int[MAX_ARRAY_SIZE]; + std::ifstream input(filename); + + while (input >> readInt) { + *(intArray + *numElements) = readInt; + *numElements += 1; + } + + std::cout << "Printing the contents of the array in reverse order: "; + + /** PART 2: MODIFY CODE BELOW **/ + + for (int i = MAX_ARRAY_SIZE; i >= -1; i--) { + // If we're at the beginning of the for loop, initalize *smallestNum + // Else, compare *smallestNum to current element in the for loop + if (i == MAX_ARRAY_SIZE) { + *smallestNum = *(intArray + i); + } + + else { + if (*smallestNum > *(intArray + i)) { + *smallestNum = *(intArray + i); + } + } + + /** PART 2: MODIFY CODE ABOVE **/ + + *sum += *(intArray + i); + std::cout << *(intArray + i) << " "; + } + + std::cout << std::endl; + if (checkCorrectSmallest(smallestNum, filename) == -1) { + std::cout << "ERROR: incorrect value for smallest number" << std::endl; + return; + } + + *avg = *sum / float(*numElements); + std::cout << "The average for the set of numbers in " << filename << " is " + << *avg << " and the smallest number is " << *smallestNum + << std::endl; + + /** PART 3: ADD AND/OR MODIFY CODE BELOW **/ + + delete intArray; + + /** PART 3: ADD AND/OR MODIFY CODE ABOVE **/ +} + +int main() { + identifyMeanAndMin("first.txt"); + std::cout << std::endl; + + identifyMeanAndMin("middle.txt"); + std::cout << std::endl; + + identifyMeanAndMin("last.txt"); + return 0; +} + diff --git a/labs/04_memory_debugging/first.txt b/labs/04_memory_debugging/first.txt new file mode 100644 index 0000000..94ebaf9 --- /dev/null +++ b/labs/04_memory_debugging/first.txt @@ -0,0 +1,4 @@ +1 +2 +3 +4 diff --git a/labs/04_memory_debugging/last.txt b/labs/04_memory_debugging/last.txt new file mode 100644 index 0000000..e0b0db9 --- /dev/null +++ b/labs/04_memory_debugging/last.txt @@ -0,0 +1,49 @@ +22 +247 +279 +240 +253 +342 +87 +181 +391 +57 +23 +302 +168 +367 +236 +240 +187 +368 +216 +185 +31 +255 +122 +140 +69 +46 +287 +69 +268 +58 +134 +330 +172 +291 +175 +63 +184 +329 +30 +337 +229 +274 +130 +95 +255 +331 +24 +325 +228 diff --git a/labs/04_memory_debugging/middle.txt b/labs/04_memory_debugging/middle.txt new file mode 100644 index 0000000..19a5cf0 --- /dev/null +++ b/labs/04_memory_debugging/middle.txt @@ -0,0 +1,10 @@ +89 +34 +13 +5 +2 +1 +3 +8 +21 +55 From e6044f9e920705843cf68334a076a52132eda931 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Sun, 17 Sep 2023 19:49:22 -0400 Subject: [PATCH 03/43] adding reference to the 4 files --- labs/04_memory_debugging/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md index fe77dfd..aff17c5 100644 --- a/labs/04_memory_debugging/README.md +++ b/labs/04_memory_debugging/README.md @@ -5,7 +5,7 @@ - Form a group of 2 members. If the number of students in the room is not divisible by 2, the graduate TA will approve a single team with 3 members. -- Introduce yourself to your teammate. Ask them to share something about themselves (e.g. hobbies, sports, favorite music, etc.) Learn something new about each of your teammates (even if you already know them). +- Introduce yourself to your teammate. Share to your teammate something about yourself (e.g. hobbies, sports, favorite music, etc). Learn something new about your teammate (even if you already know the teammate). - Following the conventions used in Data Structures lecture for memory diagramming, draw a picture of the stack and the heap that result from executing the statements below. Use a ‘?’ to represent uninitialized values. @@ -41,13 +41,18 @@ fault”, or it works on your machine but not on Submitty, try running a memory Please download the following 4 files needed for this lab: +[buggy_lab4.cpp](./buggy_lab4.cpp) +[first.txt](./first.txt) +[middle.txt](./middle.txt) +[last.txt](./last.txt) + ## Checkpoint 2 *estimate: 20-40 minutes* For Checkpoint 2 of this lab, we will revisit the final checkpoint of the first lab of this course; only this time, we will heavily rely on dynamic memory to find the average and smallest number for a set of data from an input file. You will use a memory debugging tool such as DrMemory or Valgrind to fix memory errors and -leaks in buggy lab4.cpp. Make sure to download the provided .txt files as well. +leaks in buggy_lab4.cpp. Make sure to download the provided .txt files as well. First take a look at the code inside the identifyMeanAndMin() function. You will notice that the syntax used throughout the program may be a little different than what youre used to. Try and familiarize yourself with this syntax before you start working on the assignment. What does the code *(intArray + *numElements) From 44bdfc95ba4608b52ccf5572e35b856e76188671 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Sun, 17 Sep 2023 19:58:59 -0400 Subject: [PATCH 04/43] checkpoint 2 and 3 --- labs/04_memory_debugging/README.md | 56 ++++++++++++++++-------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md index aff17c5..291f1cb 100644 --- a/labs/04_memory_debugging/README.md +++ b/labs/04_memory_debugging/README.md @@ -49,39 +49,39 @@ Please download the following 4 files needed for this lab: ## Checkpoint 2 *estimate: 20-40 minutes* -For Checkpoint 2 of this lab, we will revisit the final checkpoint of the first lab of this course; only this time, -we will heavily rely on dynamic memory to find the average and smallest number for a set of data from an -input file. You will use a memory debugging tool such as DrMemory or Valgrind to fix memory errors and -leaks in buggy_lab4.cpp. Make sure to download the provided .txt files as well. +For Checkpoint 2 of this lab, we will heavily rely on dynamic memory to find the average and smallest number for a set of data from an input file. You will use a memory debugging tool such as DrMemory or Valgrind to fix memory errors and leaks in buggy_lab4.cpp. Make sure to download the provided .txt files as well. First take a look at the code inside the identifyMeanAndMin() function. You will notice that the syntax used -throughout the program may be a little different than what youre used to. Try and familiarize yourself with -this syntax before you start working on the assignment. What does the code *(intArray + *numElements) -= readInt; do? Whats going on inside the for loop? If youre stuck on this, ask a mentor or TA for help as +throughout the program may be a little different than what you are used to. Try and familiarize yourself with +this syntax before you start working on the assignment. What does this line of code do? + +```cpp +*(intArray + *numElements) = readInt; +``` + +Whats going on inside the *for* loop? If you are stuck on this, ask a mentor or TA for help as soon as possible and refer back to your lecture notes on pointers and arrays. -Once youve done this, compile the program using: +Once you have done this, compile the program using: ```console g++ buggy_lab4.cpp -o buggy_lab4.out -g -Wall ``` -Try running the program normally using: ./buggy_lab4.out -You will notice that a segmentation fault occurs. Now run this program using either Valgrind or DrMemory. -If running using Valgrind, remember to use --leak-check=yes or --leak-check=full . +Try running the program normally using: -Your memory debugger should give you more context as to why a segmentation fault is occurring, especially -if youve compiled with -g. To complete this checkpoint, add or modify code in the areas marked Parts 1, 2, -and 3 to resolve all memory errors and leaks. As you are working on this, be sure to also think about the -questions asked in Checkpoint 3. -It is highly recommended that you tackle one part at a time. For example, after adding a few lines of code -to part 1, you will now receive different memory errors when you recompile and run the program using your -memory debugger. Similarly, fixing all memory errors in part 2 will generate different memory errors that -should be resolved in part 3. -In part 2 of buggy lab4.cpp, the goal is to print out the contents of intArray in reverse order, while also -calculating the sum of all elements in the array and keeping track of the smallest number encountered. -Solutions that attempt to print the contents of the array in a different manner or end up with the wrong -value for the smallest number found or sum wont be accepted. +```console +./buggy_lab4.out +``` + +You will notice that a segmentation fault occurs. Now run this program using either Valgrind or DrMemory. If running using Valgrind, remember to use --leak-check=yes or --leak-check=full. + +Your memory debugger should give you more context as to why a segmentation fault is occurring, especially if you have compiled with *-g*. To complete this checkpoint, add or modify code in the areas marked Parts 1, 2, and 3 to resolve all memory errors and leaks. As you are working on this, be sure to also think about the questions asked in Checkpoint 3. + +It is highly recommended that you tackle one part at a time. For example, after adding a few lines of code to part 1, you will now receive different memory errors when you recompile and run the program using your memory debugger. Similarly, fixing all memory errors in part 2 will generate different memory errors that should be resolved in part 3. + +In part 2 of buggy_lab4.cpp, the goal is to print out the contents of intArray in reverse order, while also calculating the sum of all elements in the array and keeping track of the smallest number encountered. Solutions that attempt to print the contents of the array in a different manner or end up with the wrong +value for the smallest number found or sum won't be accepted. Note that: - You are only allowed to modify or add code when asked to. This would be between the comments that -indicate parts 1, 2, and 3 inside buggy lab4.cpp. Do not modify other parts of the code or create any +indicate parts 1, 2, and 3 inside buggy_lab4.cpp. Do not modify other parts of the code or create any helper functions. - You are not allowed to declare new variables; the ones provided are more than enough. Hint: how do we create memory on the heap? @@ -89,9 +89,9 @@ we create memory on the heap? **You will receive no credit if you do not follow the above restrictions.** -**To receive credit for this checkpoint**: Fix buggy lab4.cpp so that it successfully prints out the average +**To receive credit for this checkpoint**: Fix buggy_lab4.cpp so that it successfully prints out the average and smallest number for a given set of data and is free of all memory errors and leaks on your local machine. -Submit buggy lab4.cpp on Submitty and verify that there are no memory errors there as well and show a +Submit buggy_lab4.cpp on Submitty and verify that there are no memory errors there as well and show a mentor or TA both results. Also explain to a mentor TA what you added or modified in the program to resolve all memory errors. @@ -104,10 +104,14 @@ and think about the following: flag compared to when you leave it out? 2. How would you rewrite the for loop in part 2 to use the bracket [] operator instead of pointer syntax? 3. For DrMemory users, you wouldve encountered all of these errors in parts 1, 2, or 3 of Checkpoint 2: + +```console UNITIALIZED READ UNADDRESSABLE ACCESS INVALID HEAP ARGUMENT LEAK +``` + 4. What do you think each of these errors mean? 5. For Valgrind users, the errors you will have seen are: ```console From 9ba344c58310cbc1ddfd07a20731acd122f150a1 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Sun, 17 Sep 2023 20:10:19 -0400 Subject: [PATCH 05/43] adding estimated time --- labs/04_memory_debugging/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md index 291f1cb..0b66373 100644 --- a/labs/04_memory_debugging/README.md +++ b/labs/04_memory_debugging/README.md @@ -96,6 +96,7 @@ mentor or TA both results. Also explain to a mentor TA what you added or modifie resolve all memory errors. ## Checkpoint 3 +*estimate: 15-25 minutes* As you work through Checkpoint 2, try and pay close attention the analysis given by DrMemory or Valgrind and think about the following: From adef7f1bc2277349e4e0f35634bbfd8a9d853d69 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 21:41:27 -0400 Subject: [PATCH 06/43] upload the heap image --- lectures/06_memory/heap.png | Bin 0 -> 17770 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/06_memory/heap.png diff --git a/lectures/06_memory/heap.png b/lectures/06_memory/heap.png new file mode 100644 index 0000000000000000000000000000000000000000..c8945c8ff0d79e27db244d356b6a613233dd12a6 GIT binary patch literal 17770 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 Date: Mon, 18 Sep 2023 21:52:39 -0400 Subject: [PATCH 07/43] try code and image side by side --- lectures/06_memory/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 22cb1cf..0302bf9 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -21,11 +21,14 @@ static int counter; ## 6.2 Dynamic Memory Dynamic memory is: -- created using the new operator, +- created using the **new** operator, - accessed through pointers, and -- removed through the delete operator. +- removed through the **delete** operator. Here’s a simple example involving dynamic allocation of integers: + + + + +
```cpp int * p = new int; *p = 17; @@ -42,6 +45,11 @@ cout << *p << " " << *q << endl; delete p; delete q; ``` +heap +
+ - The expression new int asks the system for a new chunk of memory that is large enough to hold an integer and returns the address of that memory. Therefore, the statement int * p = new int; allocates memory From 604718ac28df070e468afddc9e5c385a7091b0c4 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 21:55:28 -0400 Subject: [PATCH 08/43] 2nd try of code and png side by side --- lectures/06_memory/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 0302bf9..74d3d10 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -29,7 +29,7 @@ Dynamic memory is: From 1c0cdec73674eac462a08599444391b831b6d8c8 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:00:18 -0400 Subject: [PATCH 09/43] adjusting section 2 --- lectures/06_memory/README.md | 38 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 74d3d10..430a694 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -29,7 +29,8 @@ Dynamic memory is:
-```cpp +
 int * p = new int;
 *p = 17;
 cout << *p << endl;
@@ -44,7 +44,7 @@ p = temp;
 cout << *p << " " << *q << endl;
 delete p;
 delete q;
-```
+
heap
-
+
+ 
 int * p = new int;
 *p = 17;
 cout << *p << endl;
@@ -44,25 +45,38 @@ p = temp;
 cout << *p << " " << *q << endl;
 delete p;
 delete q;
-
+
+
heap
+ -- The expression new int asks the system for a new chunk of memory that is large enough to hold an integer -and returns the address of that memory. Therefore, the statement int * p = new int; allocates memory -from the heap and stores its address in the pointer variable p. -- The statement delete p; takes the integer memory pointed by p and returns it to the system for re-use. -- This memory is allocated from and returned to a special area of memory called the heap. By contrast, local -variables and function parameters are placed on the stack as discussed last lecture. -- In between the new and delete statements, the memory is treated just like memory for an ordinary variable, +- The expression *new int* asks the system for a new chunk of memory that is large enough to hold an integer +and returns the address of that memory. Therefore, the statement + +```cpp +int * p = new int; +``` + +allocates memory from the heap and stores its address in the pointer variable *p*. + +- The statement + +```cpp +delete p; +``` + +takes the integer memory pointed by *p* and returns it to the system for re-use. +- This memory is allocated from and returned to a special area of memory called the **heap**. By contrast, local +variables and function parameters are placed on the stack. +- In between the *new* and *delete* statements, the memory is treated just like memory for an ordinary variable, except the only way to access it is through pointers. Hence, the manipulation of pointer variables and values is -similar to the examples covered in Lecture 5 except that there is no explicitly named variable for that memory +similar to the examples covered in the pointers lecture except that there is no explicitly named variable for that memory other than the pointer variable. -- Dynamic allocation of primitives like ints and doubles is not very interesting or significant. What’s more -important is dynamic allocation of arrays and objects. +- Dynamic allocation of primitives like ints and doubles is not very interesting or significant. What’s more important is dynamic allocation of arrays and class objects. ## 6.3 Exercises From 0755d27b0549a7f2727079a4155125d30938ae2f Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:02:10 -0400 Subject: [PATCH 10/43] adding 1st animation --- lectures/06_memory/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 430a694..77675bb 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -78,6 +78,8 @@ similar to the examples covered in the pointers lecture except that there is no other than the pointer variable. - Dynamic allocation of primitives like ints and doubles is not very interesting or significant. What’s more important is dynamic allocation of arrays and class objects. +- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example1/index.html). + ## 6.3 Exercises - [Leetcode problem 56: Merge Intervals](https://leetcode.com/problems/merge-intervals/). Solution: [p56_mergeintervals.cpp](../../leetcode/p56_mergeintervals.cpp) From 425988d4e2125aa113d16bea12b62dd84d3951b4 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:11:25 -0400 Subject: [PATCH 11/43] upload the array image --- lectures/06_memory/array.png | Bin 0 -> 5029 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/06_memory/array.png diff --git a/lectures/06_memory/array.png b/lectures/06_memory/array.png new file mode 100644 index 0000000000000000000000000000000000000000..3636bbf612a1a747d3ed044f13f7a4ba5351e710 GIT binary patch literal 5029 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 E7xiFLBme*a literal 0 HcmV?d00001 From 408cffb997d32a7b34ce2f6c548d414aaab3b493 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:14:56 -0400 Subject: [PATCH 12/43] adding 2st animation --- lectures/06_memory/README.md | 52 +++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 77675bb..d71b98c 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -78,7 +78,57 @@ similar to the examples covered in the pointers lecture except that there is no other than the pointer variable. - Dynamic allocation of primitives like ints and doubles is not very interesting or significant. What’s more important is dynamic allocation of arrays and class objects. -- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example1/index.html). +- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example1/index.html) to see what exactly the above code snippet does. + +## 6.3 Dynamic Allocation of Arrays +- How do we allocate an array on the stack? What is the code? What memory diagram is produced by the code? +- Declaring the size of an array at compile time doesn’t offer much flexibility. Instead we can dynamically allocate an array based on data. This gets us part-way toward the behavior of the standard library vector class. Here’s an example: + + + + + +
+ +
+int main() {
+    std::cout << "Enter the size of the array: ";
+    int n,i;
+    std::cin >> n;
+    double *a = new double[n];
+    for (i=0; i
+
+
array +
+ +- The expression new double[n] asks the system to dynamically allocate enough consecutive memory to hold n +double’s (usually 8n bytes). + - What’s crucially important is that n is a variable. Therefore, its value and, as a result, the size of the +array are not known until the program is executed and the the memory must be allocated dynamically. + - The address of the start of the allocated memory is assigned to the pointer variable a. +- After this, a is treated as though it is an array. For example: a[i] = sqrt( i ); +In fact, the expression a[i] is exactly equivalent to the pointer arithmetic and dereferencing expression *(a+i) +which we have seen several times before. +- After we are done using the array, the line: delete [] a; releases the memory allocated for the entire +array and calls the destructor (we’ll learn about these soon!) for each slot of the array. Deleting a dynamically +allocated array without the [] is an error (but it may not cause a crash or other noticeable problem, depending +on the type stored in the array and the specific compiler implementation). +- Since the program is ending, releasing the memory is not a major concern. However, to demonstrate +that you understand memory allocation & deallocation, you should always delete dynamically allocated +memory in this course, even if the program is terminating. +- In more substantial programs it is ABSOLUTELY CRUCIAL. If we forget to release memory repeatedly +the program can be said to have a memory leak. Long-running programs with memory leaks will eventually +run out of memory and crash. + +- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example2/index.html) to see what exactly the above code snippet does. ## 6.3 Exercises From 79df990b2598c6577b0226f6f865758ed1834969 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:20:03 -0400 Subject: [PATCH 13/43] displaying less than --- lectures/06_memory/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index d71b98c..ae795a6 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -94,8 +94,8 @@ int main() { int n,i; std::cin >> n; double *a = new double[n]; - for (i=0; i Date: Mon, 18 Sep 2023 22:31:23 -0400 Subject: [PATCH 14/43] adding leetcode problem --- lectures/06_memory/README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index ae795a6..4e25b06 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -78,7 +78,7 @@ similar to the examples covered in the pointers lecture except that there is no other than the pointer variable. - Dynamic allocation of primitives like ints and doubles is not very interesting or significant. What’s more important is dynamic allocation of arrays and class objects. -- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example1/index.html) to see what exactly the above code snippet does. +- Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example1/index.html) to see what exactly the above code snippet does. ## 6.3 Dynamic Allocation of Arrays - How do we allocate an array on the stack? What is the code? What memory diagram is produced by the code? @@ -128,11 +128,8 @@ memory in this course, even if the program is terminating. the program can be said to have a memory leak. Long-running programs with memory leaks will eventually run out of memory and crash. -- play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example2/index.html) to see what exactly the above code snippet does. +- Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example2/index.html) to see what exactly the above code snippet does. -## 6.3 Exercises +## 6.4 Exercises -- [Leetcode problem 56: Merge Intervals](https://leetcode.com/problems/merge-intervals/). Solution: [p56_mergeintervals.cpp](../../leetcode/p56_mergeintervals.cpp) -- [Leetcode problem 905: Sort Array By Parity](https://leetcode.com/problems/sort-array-by-parity/). Solution: [p905_sortarraybyparity.cpp](../../leetcode/p905_sortarraybyparity.cpp) -- [Leetcode problem 1929: Concatenation of Array -](https://leetcode.com/problems/concatenation-of-array/). Solution: [p1929_concatenationofarray.cpp](../../leetcode/p1929_concatenationofarray.cpp) +- [Leetcode problem 1480: Running Sum of 1d Array](https://leetcode.com/problems/running-sum-of-1d-array/). Solution: [p1480_runningsumofarray.cpp](../../leetcode/p1480_runningsumofarray.cpp) From c42e5fa30d48b50c03ad95fcb137b1a5e06aa4e8 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 22:46:03 -0400 Subject: [PATCH 15/43] adding leetcode solution --- leetcode/p1480_runningsumofarray.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 leetcode/p1480_runningsumofarray.cpp diff --git a/leetcode/p1480_runningsumofarray.cpp b/leetcode/p1480_runningsumofarray.cpp new file mode 100644 index 0000000..d1440e5 --- /dev/null +++ b/leetcode/p1480_runningsumofarray.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + vector runningSum(vector& nums) { + int sum=0; + vector result; + int size = nums.size(); + // because runningSum will have size elements, and runningSum[0] is the sum of one element, i.e., nums[0]. + for(int i=1;i<(size+1);i++){ + int *a = new int[i]; + // sum stores the sum from nums[0] to nums[i] + for(int j=0;j Date: Mon, 18 Sep 2023 23:04:03 -0400 Subject: [PATCH 16/43] adding comments to the leetcode problem --- leetcode/p1480_runningsumofarray.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/leetcode/p1480_runningsumofarray.cpp b/leetcode/p1480_runningsumofarray.cpp index d1440e5..5ef43df 100644 --- a/leetcode/p1480_runningsumofarray.cpp +++ b/leetcode/p1480_runningsumofarray.cpp @@ -1,3 +1,6 @@ +// this is a very bad solution, in this problem we do not need to use dynamic memory, because std::vector automatically uses dynamic memory internally. +// the solution below therefore is just a demonstration of how to use the new and delete operator. + class Solution { public: vector runningSum(vector& nums) { From 86afd3a16ddd0767c4bee1b1b3bb1e3362a7a647 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:19:14 -0400 Subject: [PATCH 17/43] adding animation 3 --- lectures/06_memory/README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 4e25b06..480a9f2 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -130,6 +130,24 @@ run out of memory and crash. - Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/example2/index.html) to see what exactly the above code snippet does. -## 6.4 Exercises +## 6.4 Dynamic Allocation of Two-Dimensional Arrays + +To store a grid of data, we will need to allocate a top level array of pointers to arrays of the data. For example: + +```cpp +double** a = new double*[rows]; +for (int i = 0; i < rows; i++) { + a[i] = new double[cols]; + for (int j = 0; j < cols; j++) { + a[i][j] = double(i+1) / double (j+1); + } +} +``` +- Draw a picture of the resulting data structure. +- Then, write code to correctly delete all of this memory. + +- Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/two_d_array/index.html) to see what exactly the above code snippet does. + +## 6.5 Exercises - [Leetcode problem 1480: Running Sum of 1d Array](https://leetcode.com/problems/running-sum-of-1d-array/). Solution: [p1480_runningsumofarray.cpp](../../leetcode/p1480_runningsumofarray.cpp) From 7c6be9d30738cf510b36f8ed5cd18ebf96be5e52 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:41:53 -0400 Subject: [PATCH 18/43] uploading the memory exercise png file --- lectures/06_memory/memory_exercise.png | Bin 0 -> 7541 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/06_memory/memory_exercise.png diff --git a/lectures/06_memory/memory_exercise.png b/lectures/06_memory/memory_exercise.png new file mode 100644 index 0000000000000000000000000000000000000000..e58146cff9b44cf2558035d03f2cee0e4f193e59 GIT binary patch literal 7541 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 F{tpx0Dg^)l literal 0 HcmV?d00001 From 2457a6c6af093015c9aa1b97d8433167e911dadc Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:44:04 -0400 Subject: [PATCH 19/43] adding the memory debugging part --- lectures/06_memory/README.md | 268 ++++++++++++++++++++++++++++++++++- 1 file changed, 267 insertions(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 480a9f2..d1686d3 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -148,6 +148,272 @@ for (int i = 0; i < rows; i++) { - Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/two_d_array/index.html) to see what exactly the above code snippet does. -## 6.5 Exercises +## 6.5 Dynamic Allocation: Arrays of Class Objects + +We can dynamically allocate arrays of class objects. The default constructor (the constructor that takes no arguments) must be defined in order to allocate an array of objects. + +```cpp +class Foo { +public: + Foo(); + double value() const { return a*b; } +private: + int a; + double b; +}; + +Foo::Foo() { + static int counter = 1; + a = counter; + b = 100.0; + counter++; +} + +int main() { + int n; + std::cin >> n; + Foo *things = new Foo[n]; + std::cout << "size of int: " << sizeof(int) << std::endl; + std::cout << "size of double: " << sizeof(double) << std::endl; + std::cout << "size of foo object: " << sizeof(Foo) << std::endl; + for (Foo* i = things; i < things+n; i++) + std::cout << "Foo stored at: " << i << " has value " << i->value() << std::endl; + delete [] things; +} +``` + +The above program will produce the following output: + +```console +size of int: 4 +size of double: 8 +size of foo object: 16 +Foo stored at: 0x104800890 has value 100 +Foo stored at: 0x1048008a0 has value 200 +Foo stored at: 0x1048008b0 has value 300 +Foo stored at: 0x1048008c0 has value 400 +... +``` + +## 6.6 Exercises - [Leetcode problem 1480: Running Sum of 1d Array](https://leetcode.com/problems/running-sum-of-1d-array/). Solution: [p1480_runningsumofarray.cpp](../../leetcode/p1480_runningsumofarray.cpp) + +## 6.7 Memory Debugging + +In addition to the step-by-step debuggers like gdb, lldb, or the debugger in your IDE, we recommend using a memory +debugger like “Dr. Memory” (Windows, Linux, and MacOSX) or “Valgrind” (Linux and MacOSX). These tools can +detect the following problems: +- Use of uninitialized memory +- Reading/writing memory after it has been free’d (NOTE: delete calls free) +- Reading/writing off the end of malloc’d blocks (NOTE: new calls malloc) +- Reading/writing inappropriate areas on the stack +- Memory leaks - where pointers to malloc’d blocks are lost forever +- Mismatched use of malloc/new/new [] vs free/delete/delete [] +- Overlapping src and dst pointers in memcpy() and related functions + +## 6.8 Sample Buggy Program + +Can you see the errors in this program? + +```cpp +1 #include +2 +3 int main() { +4 +5 int *p = new int; +6 if (*p != 10) std::cout << "hi" << std::endl; +7 +8 int *a = new int[3]; +9 a[3] = 12; +10 delete a; +11 +12 } +``` + +## 6.9 Using Dr. Memory http://www.drmemory.org + +Here’s how Dr. Memory reports the errors in the above program: + +```console +~~Dr.M~~ Dr. Memory version 1.8.0 +~~Dr.M~~ +~~Dr.M~~ Error #1: UNINITIALIZED READ: reading 4 byte(s) +~~Dr.M~~ # 0 main [memory_debugger_test.cpp:6] +hi +~~Dr.M~~ +~~Dr.M~~ Error #2: UNADDRESSABLE ACCESS beyond heap bounds: writing 4 byte(s) +~~Dr.M~~ # 0 main [memory_debugger_test.cpp:9] +~~Dr.M~~ Note: refers to 0 byte(s) beyond last valid byte in prior malloc +~~Dr.M~~ +~~Dr.M~~ Error #3: INVALID HEAP ARGUMENT: allocated with operator new[], freed with operator delete +~~Dr.M~~ # 0 replace_operator_delete [/drmemory_package/common/alloc_replace.c:2684] +~~Dr.M~~ # 1 main [memory_debugger_test.cpp:10] +~~Dr.M~~ Note: memory was allocated here: +~~Dr.M~~ Note: # 0 replace_operator_new_array [/drmemory_package/common/alloc_replace.c:2638] +~~Dr.M~~ Note: # 1 main [memory_debugger_test.cpp:8] +~~Dr.M~~ +~~Dr.M~~ Error #4: LEAK 4 bytes +~~Dr.M~~ # 0 replace_operator_new [/drmemory_package/common/alloc_replace.c:2609] +~~Dr.M~~ # 1 main [memory_debugger_test.cpp:5] +~~Dr.M~~ +~~Dr.M~~ ERRORS FOUND: +~~Dr.M~~ 1 unique, 1 total unaddressable access(es) +~~Dr.M~~ 1 unique, 1 total uninitialized access(es) +~~Dr.M~~ 1 unique, 1 total invalid heap argument(s) +~~Dr.M~~ 0 unique, 0 total warning(s) +~~Dr.M~~ 1 unique, 1 total, 4 byte(s) of leak(s) +~~Dr.M~~ 0 unique, 0 total, 0 byte(s) of possible leak(s) +~~Dr.M~~ Details: /DrMemory-MacOS-1.8.0-8/drmemory/logs/DrMemory-a.out.7726.000/results.txt +``` + +And the fixed version: + +```console +~~Dr.M~~ Dr. Memory version 1.8.0 +hi +~~Dr.M~~ +~~Dr.M~~ NO ERRORS FOUND: +~~Dr.M~~ 0 unique, 0 total unaddressable access(es) +~~Dr.M~~ 0 unique, 0 total uninitialized access(es) +~~Dr.M~~ 0 unique, 0 total invalid heap argument(s) +~~Dr.M~~ 0 unique, 0 total warning(s) +~~Dr.M~~ 0 unique, 0 total, 0 byte(s) of leak(s) +~~Dr.M~~ 0 unique, 0 total, 0 byte(s) of possible leak(s) +~~Dr.M~~ Details: /DrMemory-MacOS-1.8.0-8/drmemory/logs/DrMemory-a.out.7762.000/results.txt +``` + +**Note**: Dr. Memory on Windows with the Visual Studio compiler may not report a mismatched free() / delete +/ delete [] error (e.g., line 10 of the sample code above). This may happen if optimizations are enabled and the +objects stored in the array are simple and do not have their own dynamically-allocated memory that lead to their +own indirect memory leaks. + +## 6.10 Using Valgrind http://valgrind.org/ + +And this is how Valgrind reports the same errors: + +```console +==31226== Memcheck, a memory error detector +==31226== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==31226== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info +==31226== Command: ./a.out +==31226== +==31226== Conditional jump or move depends on uninitialised value(s) +==31226== at 0x40096F: main (memory_debugger_test.cpp:6) +==31226== +hi +==31226== Invalid write of size 4 +==31226== at 0x4009A3: main (memory_debugger_test.cpp:9) +==31226== Address 0x4c3f09c is 0 bytes after a block of size 12 alloc'd +==31226== at 0x4A0700A: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==31226== by 0x400996: main (memory_debugger_test.cpp:8) +==31226== +==31226== Mismatched free() / delete / delete [] +==31226== at 0x4A07991: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==31226== by 0x4009B4: main (memory_debugger_test.cpp:10) +==31226== Address 0x4c3f090 is 0 bytes inside a block of size 12 alloc'd +==31226== at 0x4A0700A: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==31226== by 0x400996: main (memory_debugger_test.cpp:8) +==31226== +==31226== +==31226== HEAP SUMMARY: +==31226== in use at exit: 4 bytes in 1 blocks +==31226== total heap usage: 2 allocs, 1 frees, 16 bytes allocated +==31226== +==31226== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 +==31226== at 0x4A06965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==31226== by 0x400961: main (memory_debugger_test.cpp:5) +==31226== +==31226== LEAK SUMMARY: +==31226== definitely lost: 4 bytes in 1 blocks +==31226== indirectly lost: 0 bytes in 0 blocks +==31226== possibly lost: 0 bytes in 0 blocks +==31226== still reachable: 0 bytes in 0 blocks +==31226== suppressed: 0 bytes in 0 blocks +==31226== +==31226== For counts of detected and suppressed errors, rerun with: -v +==31226== Use --track-origins=yes to see where uninitialised values come from +==31226== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 2 from 2) +``` + +And here’s what it looks like after fixing those bugs: + +```console +==31252== Memcheck, a memory error detector +==31252== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==31252== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info +==31252== Command: ./a.out +==31252== +hi +==31252== +==31252== HEAP SUMMARY: +==31252== in use at exit: 0 bytes in 0 blocks +==31252== total heap usage: 2 allocs, 2 frees, 16 bytes allocated +==31252== +==31252== All heap blocks were freed -- no leaks are possible +==31252== +==31252== For counts of detected and suppressed errors, rerun with: -v +==31252== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) +``` + +## 6.11 How to use a memory debugger + +- Detailed instructions on installation & use of these tools are available here: +http://www.cs.rpi.edu/academics/courses/fall23/csci1200/memory_debugging.php +- Memory errors (uninitialized memory, out-of-bounds read/write, use after free) may cause seg faults, crashes, +or strange output. +- Memory leaks on the other hand will never cause incorrect output, but your program will be inefficient and +hog system resources. A program with a memory leak may waste so much memory it causes all programs on +the system to slow down significantly or it may crash the program or the whole operating system if the system +runs out of memory (this takes a while on modern computers with lots of RAM & harddrive space). +- For many future homeworks, Submitty will be configured to run your code with Dr. Memory to search for +memory problems and present the output with the submission results. For full credit your program must be +memory error and memory leak free! +- A program that seems to run perfectly fine on one computer may still have significant memory errors. Running +a memory debugger will help find issues that might break your homework on another computer or when +submitted to the homework server. +- **Important Note**: When these tools find a memory leak, they point to the line of code where this memory +was allocated. These tools does not understand the program logic and thus obviously cannot tell us where it +should have been deleted. +- A final note: STL and other 3rd party libraries are highly optimized and sometimes do sneaky but correct and +bug-free tricks for efficiency that confuse the memory debugger. For example, because the STL string class +uses its own allocator, there may be a warning about memory that is “still reachable” even though you’ve +deleted all your dynamically allocated memory. The memory debuggers have automatic suppressions for some +of these known “false positives”, so you will see this listed as a “suppressed leak”. So don’t worry if you see +those messages. + +## 6.12 Diagramming Memory Exercises + +- Draw a diagram of the heap and stack memory for each segment of code below. Use a “?” to indicate that the +value of the memory is uninitialized. Indicate whether there are any errors or memory leaks during execution +of this code. + +```cpp +class Foo { +public: + double x; + int* y; +}; +Foo a; +a.x = 3.14159; +Foo *b = new Foo; +(*b).y = new int[2]; +Foo *c = b; +a.y = b->y; +c->y[1] = 7; +b = NULL; +``` + +```cpp +int a[5] = { 10, 11, 12, 13, 14 }; +int *b = a + 2; +*b = 7; +int *c = new int[3]; +c[0] = b[0]; +c[1] = b[1]; +c = &(a[3]); +``` + +Write code to produce this diagram: + +[alt text](memory_exercise.png "memory exercise") From 1b0c079b52b14ffebf8248062e2a718ae6a64085 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:45:49 -0400 Subject: [PATCH 20/43] fixing the image displaying issue --- lectures/06_memory/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index d1686d3..bbf55ac 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -52,7 +52,7 @@ delete q; - + - The expression *new int* asks the system for a new chunk of memory that is large enough to hold an integer and returns the address of that memory. Therefore, the statement @@ -416,4 +416,4 @@ c = &(a[3]); Write code to produce this diagram: -[alt text](memory_exercise.png "memory exercise") +![alt text](memory_exercise.png "memory exercise") From 15be49e5367f96ac85174d2590a857cf3293fb1b Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:46:35 -0400 Subject: [PATCH 21/43] separate the three problems --- lectures/06_memory/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index bbf55ac..633e8c9 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -414,6 +414,6 @@ c[1] = b[1]; c = &(a[3]); ``` -Write code to produce this diagram: +- Write code to produce this diagram: ![alt text](memory_exercise.png "memory exercise") From b9699e5447aa8a5e7f6c5fbd57b76b982aeb37ff Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:54:27 -0400 Subject: [PATCH 22/43] adding the solution images --- .../06_memory/memory_exercise1_solution.png | Bin 0 -> 9582 bytes .../06_memory/memory_exercise2_solution.png | Bin 0 -> 14199 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/06_memory/memory_exercise1_solution.png create mode 100644 lectures/06_memory/memory_exercise2_solution.png diff --git a/lectures/06_memory/memory_exercise1_solution.png b/lectures/06_memory/memory_exercise1_solution.png new file mode 100644 index 0000000000000000000000000000000000000000..dd0e6bc64f8d6b1657308029ef1b558960b8982b GIT binary patch literal 9582 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%0D1kD=u_sP%=FJ0tpP9xevA9n=#N@#<>@<@e9OM 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%0DO9t4q8|Rz+AmbvpIPwJ}w^NJ>5?uj=x>o z<=5g{|Gy@2J42uKIa~#0`KK~3-4ISd?QWt|B>W7`nOenV&gj%9)zRy zm|IXm8E~zwjlbuZxb Date: Mon, 18 Sep 2023 23:55:35 -0400 Subject: [PATCH 23/43] adding links to solutions --- lectures/06_memory/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 633e8c9..ca69e03 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -404,6 +404,8 @@ c->y[1] = 7; b = NULL; ``` +See [solution](memory_exercise1_solution.png) + ```cpp int a[5] = { 10, 11, 12, 13, 14 }; int *b = a + 2; @@ -414,6 +416,8 @@ c[1] = b[1]; c = &(a[3]); ``` +See [solution](memory_exercise2_solution.png) + - Write code to produce this diagram: ![alt text](memory_exercise.png "memory exercise") From 55816767665d6dba0b16654c5a3e3f7299ce0d8f Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Mon, 18 Sep 2023 23:58:22 -0400 Subject: [PATCH 24/43] adding solution to exercise 3 --- lectures/06_memory/README.md | 6 ++++-- lectures/06_memory/memory_exercise3_solution.cpp | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 lectures/06_memory/memory_exercise3_solution.cpp diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index ca69e03..842f480 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -404,7 +404,7 @@ c->y[1] = 7; b = NULL; ``` -See [solution](memory_exercise1_solution.png) +See [solution](memory_exercise1_solution.png). ```cpp int a[5] = { 10, 11, 12, 13, 14 }; @@ -416,8 +416,10 @@ c[1] = b[1]; c = &(a[3]); ``` -See [solution](memory_exercise2_solution.png) +See [solution](memory_exercise2_solution.png). - Write code to produce this diagram: ![alt text](memory_exercise.png "memory exercise") + +See [solution](memory_exercise3_solution.cpp). diff --git a/lectures/06_memory/memory_exercise3_solution.cpp b/lectures/06_memory/memory_exercise3_solution.cpp new file mode 100644 index 0000000..429f42f --- /dev/null +++ b/lectures/06_memory/memory_exercise3_solution.cpp @@ -0,0 +1,8 @@ +double a[3]; +double *b = new double[3]; +a[0] = 4.2; +a[1] = 8.6; +a[2] = 2.9; +b[0] = 6.5; +b[1] = 5.1; +b[2] = 3.4; From 4804683f1df32545d155463e054f64d252ce493a Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 00:00:28 -0400 Subject: [PATCH 25/43] add the memory leak note --- lectures/06_memory/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index 842f480..bd882a7 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -416,7 +416,7 @@ c[1] = b[1]; c = &(a[3]); ``` -See [solution](memory_exercise2_solution.png). +See [solution](memory_exercise2_solution.png). Note that there is a memory leak of 3 *int*s in this program. - Write code to produce this diagram: From d977af4cd513ef3e3df847052c120b182a60b88f Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 00:04:14 -0400 Subject: [PATCH 26/43] adding the leak question --- lectures/06_memory/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/06_memory/README.md b/lectures/06_memory/README.md index bd882a7..892e578 100644 --- a/lectures/06_memory/README.md +++ b/lectures/06_memory/README.md @@ -416,7 +416,7 @@ c[1] = b[1]; c = &(a[3]); ``` -See [solution](memory_exercise2_solution.png). Note that there is a memory leak of 3 *int*s in this program. +See [solution](memory_exercise2_solution.png). Note that there is a memory leak of 3 *int*s in this program. Do you see why? - Write code to produce this diagram: From fcbb7fe85dcb41c2375576ae46222ac884b4774e Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 21:31:07 -0400 Subject: [PATCH 27/43] adding the programs --- labs/04_memory_debugging/README.md | 17 +++++------------ labs/04_memory_debugging/dessert.cpp | 10 ++++++++++ labs/04_memory_debugging/fruits.cpp | 10 ++++++++++ labs/04_memory_debugging/grains.cpp | 10 ++++++++++ labs/04_memory_debugging/protein.cpp | 11 +++++++++++ labs/04_memory_debugging/veggies.cpp | 10 ++++++++++ 6 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 labs/04_memory_debugging/dessert.cpp create mode 100644 labs/04_memory_debugging/fruits.cpp create mode 100644 labs/04_memory_debugging/grains.cpp create mode 100644 labs/04_memory_debugging/protein.cpp create mode 100644 labs/04_memory_debugging/veggies.cpp diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md index 0b66373..1f067fc 100644 --- a/labs/04_memory_debugging/README.md +++ b/labs/04_memory_debugging/README.md @@ -9,18 +9,11 @@ - Following the conventions used in Data Structures lecture for memory diagramming, draw a picture of the stack and the heap that result from executing the statements below. Use a ‘?’ to represent uninitialized values. -```cpp -char*** carrot; -char** broccoli; -char* tomato; -char radish = 'q'; -tomato = new char; -*tomato = 'z'; -broccoli = new char*; -*broccoli = tomato; -carrot = new char**; -*carrot = broccoli; -``` +[Program 1](fruits.cpp) +[Program 2](grains.cpp) +[Program 3](desserts.cpp) +[Program 4](veggies.cpp) +[Program 5](protein.cpp) Show your diagram to your teammate, and ask the teammate to reverse engineer code for your diagram; at the same time, you reverse engineer code for your teammate's diagram. diff --git a/labs/04_memory_debugging/dessert.cpp b/labs/04_memory_debugging/dessert.cpp new file mode 100644 index 0000000..7adc7a9 --- /dev/null +++ b/labs/04_memory_debugging/dessert.cpp @@ -0,0 +1,10 @@ +bool** cake; +bool pie; +bool fudge; +pie = true; +cake = new bool*[5]; +cake[1] = &pie; +bool* donut = new bool; +*donut = false; +cake[2] = donut; +cake[4] = &fudge; diff --git a/labs/04_memory_debugging/fruits.cpp b/labs/04_memory_debugging/fruits.cpp new file mode 100644 index 0000000..be8a768 --- /dev/null +++ b/labs/04_memory_debugging/fruits.cpp @@ -0,0 +1,10 @@ +int pear = 3; +int* apple; +int banana[pear]; +int* orange; +apple = new int[pear]; +orange = &banana[1]; +apple[0] = 6; +apple[1] = 7; +apple[2] = 8; +*orange = 5; diff --git a/labs/04_memory_debugging/grains.cpp b/labs/04_memory_debugging/grains.cpp new file mode 100644 index 0000000..32dfed6 --- /dev/null +++ b/labs/04_memory_debugging/grains.cpp @@ -0,0 +1,10 @@ +float* oat[3]; +oat[1] = new float; +*oat[1] = 3.14; +oat[2] = new float; +*oat[2] = 6.02; +float rice; +float* wheat; +wheat = oat[2]; +float** barley = new float*; +*barley = oat[1]; diff --git a/labs/04_memory_debugging/protein.cpp b/labs/04_memory_debugging/protein.cpp new file mode 100644 index 0000000..fb179f8 --- /dev/null +++ b/labs/04_memory_debugging/protein.cpp @@ -0,0 +1,11 @@ +int tofu = 3; +int chicken = 2; +double** fish = new double*[tofu]; +for (int beef = 0; beef < tofu; beef++) { + fish[beef] = new double[chicken]; +} +fish[0][0] = 1.41421; +fish[0][1] = 1.61803; +fish[1][0] = 2.71828; +fish[1][1] = 3.14159; +fish[2][0] = 6.02214; diff --git a/labs/04_memory_debugging/veggies.cpp b/labs/04_memory_debugging/veggies.cpp new file mode 100644 index 0000000..ad75f22 --- /dev/null +++ b/labs/04_memory_debugging/veggies.cpp @@ -0,0 +1,10 @@ +char*** carrot; +char** broccoli; +char* tomato; +char radish = 'q'; +tomato = new char; +*tomato = 'z'; +broccoli = new char*; +*broccoli = tomato; +carrot = new char**; +*carrot = broccoli; From 6c2234d0f83b127f6d0926d0ba5426f2b7857890 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 21:34:20 -0400 Subject: [PATCH 28/43] programs to code snippets --- labs/04_memory_debugging/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/labs/04_memory_debugging/README.md b/labs/04_memory_debugging/README.md index 1f067fc..1b17483 100644 --- a/labs/04_memory_debugging/README.md +++ b/labs/04_memory_debugging/README.md @@ -7,13 +7,13 @@ - Introduce yourself to your teammate. Share to your teammate something about yourself (e.g. hobbies, sports, favorite music, etc). Learn something new about your teammate (even if you already know the teammate). -- Following the conventions used in Data Structures lecture for memory diagramming, draw a picture of the stack and the heap that result from executing the statements below. Use a ‘?’ to represent uninitialized values. +- Our TA/mentor will pick a code snippet for each student, from the following 5 code snippets. Following the conventions used in Data Structures lecture for memory diagramming, draw a picture of the stack and the heap that result from executing the code snippet. Use a ‘?’ to represent uninitialized values. -[Program 1](fruits.cpp) -[Program 2](grains.cpp) -[Program 3](desserts.cpp) -[Program 4](veggies.cpp) -[Program 5](protein.cpp) +[Code Snippet 1](fruits.cpp) +[Code Snippet 2](grains.cpp) +[Code Snippet 3](desserts.cpp) +[Code Snippet 4](veggies.cpp) +[Code Snippet 5](protein.cpp) Show your diagram to your teammate, and ask the teammate to reverse engineer code for your diagram; at the same time, you reverse engineer code for your teammate's diagram. From 98625fc4b63ee44e732e3f7cecbd668a1137211b Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 21:35:30 -0400 Subject: [PATCH 29/43] rename to desserts --- labs/04_memory_debugging/{dessert.cpp => desserts.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename labs/04_memory_debugging/{dessert.cpp => desserts.cpp} (100%) diff --git a/labs/04_memory_debugging/dessert.cpp b/labs/04_memory_debugging/desserts.cpp similarity index 100% rename from labs/04_memory_debugging/dessert.cpp rename to labs/04_memory_debugging/desserts.cpp From bec9b6bff71ecaf2a47ea0161a7573ee3d1a96f0 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 22:59:08 -0400 Subject: [PATCH 30/43] adding lecture notes for big o --- .../07_order_notation_recursion/README.md | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 lectures/07_order_notation_recursion/README.md diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md new file mode 100644 index 0000000..be4b706 --- /dev/null +++ b/lectures/07_order_notation_recursion/README.md @@ -0,0 +1,272 @@ +# Lecture 7 --- Order Notation & Basic Recursion + +- Algorithm Analysis, Formal Definition of Order Notation +- Simple recursion, Visualization of recursion, Iteration vs. Recursion +- “Rules” for writing recursive functions, Lots of examples + +## 7.1 Algorithm Analysis + +Why should we bother? + - We want to do better than just implementing and testing every idea we have. + - We want to know why one algorithm is better than another. + - We want to know the best we can do. (This is often quite hard.) +How do we do it? There are several options, including: + - Don’t do any analysis; just use the first algorithm you can think of that works. + - Implement and time algorithms to choose the best. + - Analyze algorithms by counting operations while assigning different weights to different types of operations +based on how long each takes. + - Analyze algorithms by assuming each operation requires the same amount of time. Count the total number of +operations, and then multiply this count by the average cost of an operation. + +## 7.2 Exercise: Counting Example + +- Suppose arr is an array of n doubles. Here is a simple fragment of code to sum of the values in the array: +```cpp +double sum = 0; +for (int i=0; i 0 +1 n == 0 + Computing integer powers is defined as: +n +p = +( +n · n +p−1 p > 0 +1 p == 0 + These are both examples of recursive definitions + +## 7.11 Recursive C++ Functions + +C++, like other modern programming languages, allows functions to call themselves. This gives a direct method of +implementing recursive functions. Here are the recursive implementations of factorial and integer power: + +```cpp +int fact(int n) { + if (n == 0) { + return 1; + } else { + int result = fact(n-1); + return n * result; + } +} +``` + +```cpp +int intpow(int n, int p) { + if (p == 0) { + return 1; + } else { + return n * intpow( n, p-1 ); + } +} +``` + +## 7.12 The Mechanism of Recursive Function Calls + +- For each recursive call (or any function call), a program creates an activation record to keep track of: + – Completely separate instances of the parameters and local variables for the newly-called function. + – The location in the calling function code to return to when the newly-called function is complete. (Who +asked for this function to be called? Who wants the answer?) + – Which activation record to return to when the function is done. For recursive functions this can be +confusing since there are multiple activation records waiting for an answer from the same function. +- This is illustrated in the following diagram of the call fact(4). Each box is an activation record, the solid lines +indicate the function calls, and the dashed lines indicate the returns. Inside of each box we list the parameters +and local variables and make notes about the computation. +- This chain of activation records is stored in a special part of program memory called the stack + +## 7.13 Iteration vs. Recursion + +- Each of the above functions could also have been written using a for or while loop, i.e. iteratively. For example, here is an iterative +version of factorial: + +```cpp +int ifact(int n) { +int result = 1; +for (int i=1; i<=n; ++i) +result = result * i; +return result; +} +``` + +- Often writing recursive functions is more natural than writing iterative functions, especially for a first draft of +a problem implementation. +- You should learn how to recognize whether an implementation is recursive or iterative, and practice rewriting +one version as the other. Note: We’ll see that not all recursive functions can be easily rewritten in iterative +form! +- Note: The order notation for the number of operations for the recursive and iterative versions of an algorithm +is usually the same. However in C, C++, Java, and some other languages, iterative functions are generally +faster than their corresponding recursive functions. This is due to the overhead of the function call mechanism. +Compiler optimizations will sometimes (but not always!) reduce the performance hit by automatically eliminating +the recursive function calls. This is called tail call optimization. + +## 7.14 Exercises + +1. Draw a picture to illustrate the activation records for the function call +cout << intpow(4, 4) << endl; +2. Write an iterative version of intpow. +3. What is the order notation for the two versions of intpow? + +## 7.15 Rules for Writing Recursive Functions + +Here is an outline of five steps that are useful in writing and debugging recursive functions. Note: You don’t have +to do them in exactly this order... +1. Handle the base case(s). +2. Define the problem solution in terms of smaller instances of the problem. Use wishful thinking, i.e., if someone +else solves the problem of fact(4) I can extend that solution to solve fact(5). This defines the necessary +recursive calls. It is also the hardest part! +3. Figure out what work needs to be done before making the recursive call(s). +4. Figure out what work needs to be done after the recursive call(s) complete(s) to finish the computation. (What +are you going to do with the result of the recursive call?) +5. Assume the recursive calls work correctly, but make sure they are progressing toward the base case(s)! + +## 7.16 Location of the Recursive Call — Example: Printing the Contents of a Vector + + Here is a function to print the contents of a vector. Actually, it’s two functions: a driver function, and a true +recursive function. It is common to have a driver function that just initializes the first recursive function call. + +```cpp +void print_vec(std::vector& v, unsigned int i) { +if (i < v.size()) { +cout << i << ": " << v[i] << endl; +print_vec(v, i+1); +} +} +``` + +```cpp +void print_vec(std::vector& v) { +print_vec(v, 0); +} +``` + + What will this print when called in the following code? +```cpp +int main() { +std::vector a; +a.push_back(3); a.push_back(5); a.push_back(11); a.push_back(17); +print_vec(a); +} +``` + How can you change the second print vec function as little as possible so that this code prints the contents +of the vector in reverse order? From b56364a169e4edbf8d608ee93603ba35afb83d59 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:07:47 -0400 Subject: [PATCH 31/43] fixing formatting issues --- lectures/07_order_notation_recursion/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index be4b706..7f4da1d 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -74,8 +74,6 @@ quadratic root. - O(n2), O(n3), O(nk), a.k.a. POLYNOMIAL. e.g., find closest pair of points. - O(2n), O(kn), a.k.a. EXPONENTIAL. e.g., Fibonacci, playing chess. -- Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/dynamic_memory/two_d_array/index.html) to see what exactly the above code snippet does. - ## 7.6 Exercise: A Slightly Harder Example Here’s an algorithm to determine if the value stored in variable x is also in an array called foo. Can you analyze @@ -86,8 +84,8 @@ in the array (if at all)? int loc=0; bool found = false; while (!found && loc < n) { -if (x == foo[loc]) found = true; -else loc++; + if (x == foo[loc]) found = true; + else loc++; } if (found) cout << "It is there!\n"; ``` From a3d247631935ff87cd33f2ec13224dca75772310 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:09:03 -0400 Subject: [PATCH 32/43] upload factorial equation image --- .../factorial_equation.png | Bin 0 -> 3932 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/07_order_notation_recursion/factorial_equation.png diff --git a/lectures/07_order_notation_recursion/factorial_equation.png b/lectures/07_order_notation_recursion/factorial_equation.png new file mode 100644 index 0000000000000000000000000000000000000000..f72ac741f6acc5326a26029acbc891f6bfead4f2 GIT binary patch literal 3932 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 H3l;qzDHv1u literal 0 HcmV?d00001 From 6dcb0a83a622d387da1b3ca928ff4c4c0857c8ff Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:11:04 -0400 Subject: [PATCH 33/43] show factorial equation --- lectures/07_order_notation_recursion/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index 7f4da1d..93bff66 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -141,18 +141,18 @@ for (int j=i; j 0 -1 n == 0 - Computing integer powers is defined as: +- Factorial is defined for non-negative integers as: +![alt text](factorial_equation.png "factorial equation") + +- Computing integer powers is defined as: n p = ( n · n p−1 p > 0 1 p == 0 - These are both examples of recursive definitions + +These are both examples of recursive definitions ## 7.11 Recursive C++ Functions From 8cea2a17b051066770639a67c045527e5705ba9c Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:12:56 -0400 Subject: [PATCH 34/43] upload power equation image --- .../power_equation.png | Bin 0 -> 4233 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/07_order_notation_recursion/power_equation.png diff --git a/lectures/07_order_notation_recursion/power_equation.png b/lectures/07_order_notation_recursion/power_equation.png new file mode 100644 index 0000000000000000000000000000000000000000..ad8ad4fad7db3e118e575c4f959bb2da08e938c1 GIT binary patch literal 4233 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 literal 0 HcmV?d00001 From 5312773e4df9497a22b69c47b02556e2f381cf58 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:13:34 -0400 Subject: [PATCH 35/43] adding power equation --- lectures/07_order_notation_recursion/README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index 93bff66..d390329 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -145,12 +145,7 @@ for (int j=i; j 0 -1 p == 0 +![alt text](power_equation.png "power equation") These are both examples of recursive definitions From 4eccba0c7b0782b0fbe4a7f481199a9104cf4ae0 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:16:35 -0400 Subject: [PATCH 36/43] move image a little down --- lectures/07_order_notation_recursion/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index d390329..ff51b2a 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -145,9 +145,11 @@ for (int j=i; j ![alt text](power_equation.png "power equation") + -These are both examples of recursive definitions +These are both examples of recursive definitions. ## 7.11 Recursive C++ Functions From a510e367eb822cf81a2b18a94a5d4247789b4644 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:21:49 -0400 Subject: [PATCH 37/43] uploading activation records image --- .../activation_records.png | Bin 0 -> 22291 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lectures/07_order_notation_recursion/activation_records.png diff --git a/lectures/07_order_notation_recursion/activation_records.png b/lectures/07_order_notation_recursion/activation_records.png new file mode 100644 index 0000000000000000000000000000000000000000..a649d5702225628f9d33a3dd528e172b71c5cd0e GIT binary patch literal 22291 zcmdSBWn5d$+BaHSpvB$YU4py2Q{1gcf#R+$?v�R@~i62=4C1ofIeNN%!9OexKia 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 literal 0 HcmV?d00001 From 538ec774a7303ab3edc3c7fc59a57707aa89a1f6 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:23:14 -0400 Subject: [PATCH 38/43] displaying activation records --- .../07_order_notation_recursion/README.md | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index ff51b2a..b4a54f4 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -145,9 +145,7 @@ for (int j=i; j ![alt text](power_equation.png "power equation") - These are both examples of recursive definitions. @@ -188,6 +186,7 @@ confusing since there are multiple activation records waiting for an answer from - This is illustrated in the following diagram of the call fact(4). Each box is an activation record, the solid lines indicate the function calls, and the dashed lines indicate the returns. Inside of each box we list the parameters and local variables and make notes about the computation. +![alt_text](activation_records.png "chain of activation records") - This chain of activation records is stored in a special part of program memory called the stack ## 7.13 Iteration vs. Recursion @@ -197,10 +196,10 @@ version of factorial: ```cpp int ifact(int n) { -int result = 1; -for (int i=1; i<=n; ++i) -result = result * i; -return result; + int result = 1; + for (int i=1; i<=n; ++i) + result = result * i; + return result; } ``` @@ -242,25 +241,25 @@ recursive function. It is common to have a driver function that just initializes ```cpp void print_vec(std::vector& v, unsigned int i) { -if (i < v.size()) { -cout << i << ": " << v[i] << endl; -print_vec(v, i+1); -} + if (i < v.size()) { + cout << i << ": " << v[i] << endl; + print_vec(v, i+1); + } } ``` ```cpp void print_vec(std::vector& v) { -print_vec(v, 0); + print_vec(v, 0); } ``` What will this print when called in the following code? ```cpp int main() { -std::vector a; -a.push_back(3); a.push_back(5); a.push_back(11); a.push_back(17); -print_vec(a); + std::vector a; + a.push_back(3); a.push_back(5); a.push_back(11); a.push_back(17); + print_vec(a); } ``` How can you change the second print vec function as little as possible so that this code prints the contents From ae49c7097adaeb4cdc6aed79e85e5cbc0547acf2 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:25:57 -0400 Subject: [PATCH 39/43] show the table --- lectures/07_order_notation_recursion/README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index b4a54f4..f33dcd6 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -33,14 +33,13 @@ sum += arr[i]; A venture capitalist is trying to decide which of 3 startup companies to invest in and has asked for your help. Here’s the timing data for their prototype software on some different size test cases: -```console -n foo-a foo-b foo-c -10 10 u-sec 5 u-sec 1 u-sec -20 13 u-sec 10 u-sec 8 u-sec -30 15 u-sec 15 u-sec 27 u-sec -100 20 u-sec 50 u-sec 1000 u-sec -1000 ? ? ? -``` +| n | foo-a | foo-b | foo-c | +|-------|----------|----------|----------| +| 10 | 10 u-sec| 5 u-sec | 1 u-sec | +| 20 | 13 u-sec| 10 u-sec | 8 u-sec | +| 30 | 15 u-sec| 15 u-sec | 27 u-sec | +| 100 | 20 u-sec| 50 u-sec | 1000 u-sec| +| 1000 | ? | ? | ? | Which company has the “best” algorithm? From 7eb51a88dadfefd36f2abeaedce53e7b3e6cc76e Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:26:52 -0400 Subject: [PATCH 40/43] adding indent --- lectures/07_order_notation_recursion/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index f33dcd6..c202b5b 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -24,7 +24,7 @@ operations, and then multiply this count by the average cost of an operation. ```cpp double sum = 0; for (int i=0; i Date: Tue, 19 Sep 2023 23:29:25 -0400 Subject: [PATCH 41/43] testing superscript --- lectures/07_order_notation_recursion/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index c202b5b..e079f16 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -70,7 +70,7 @@ quadratic root. - O(log n), a.k.a. LOGARITHMIC. e.g., dictionary lookup, binary search. - O(n), a.k.a. LINEAR. e.g., sum up a list. - O(n log n), e.g., sorting. -- O(n2), O(n3), O(nk), a.k.a. POLYNOMIAL. e.g., find closest pair of points. +- O(n2), O(n3), O(nk), a.k.a. POLYNOMIAL. e.g., find closest pair of points. - O(2n), O(kn), a.k.a. EXPONENTIAL. e.g., Fibonacci, playing chess. ## 7.6 Exercise: A Slightly Harder Example From 91f3d5fb3559d02983c145b76b8006a74bb4f1d6 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:32:54 -0400 Subject: [PATCH 42/43] testing subscripting --- lectures/07_order_notation_recursion/README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index e079f16..58e2136 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -47,14 +47,10 @@ Which company has the “best” algorithm? In this course we will focus on the intuition of order notation. This topic will be covered again, in more depth, in later computer science courses. -- Definition: Algorithm A is order f(n) — denoted O(f(n)) — if constants k and n0 exist such that A requires -no more than k ∗ f(n) time units (operations) to solve a problem of size n ≥ n0. +- Definition: Algorithm A is order f(n) — denoted O(f(n)) — if constants k and n0 exist such that A requires no more than k * f(n) time units (operations) to solve a problem of size n ≥ n0. - For example, algorithms requiring 3n + 2, 5n − 3, and 14 + 17n operations are all O(n). This is because we can select values for k and n0 such that the definition above holds. (What values?) -Likewise, algorithms requiring n 2/10 + 15n − 3 and 10000 + 35n -2 are all O(n -2 -). +Likewise, algorithms requiring n2/10 + 15n − 3 and 10000 + 35n2 are all O(n2). - Intuitively, we determine the order by finding the asymptotically dominant term (function of n) and throwing out the leading constant. This term could involve logarithmic or exponential functions of n. Implications for analysis: @@ -71,7 +67,7 @@ quadratic root. - O(n), a.k.a. LINEAR. e.g., sum up a list. - O(n log n), e.g., sorting. - O(n2), O(n3), O(nk), a.k.a. POLYNOMIAL. e.g., find closest pair of points. -- O(2n), O(kn), a.k.a. EXPONENTIAL. e.g., Fibonacci, playing chess. +- O(2n), O(kn), a.k.a. EXPONENTIAL. e.g., Fibonacci, playing chess. ## 7.6 Exercise: A Slightly Harder Example From 611be3742a17597fe2f2b0ee3a56e512635ce735 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 19 Sep 2023 23:33:42 -0400 Subject: [PATCH 43/43] sup to sub --- lectures/07_order_notation_recursion/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/07_order_notation_recursion/README.md b/lectures/07_order_notation_recursion/README.md index 58e2136..6e12c3b 100644 --- a/lectures/07_order_notation_recursion/README.md +++ b/lectures/07_order_notation_recursion/README.md @@ -47,7 +47,7 @@ Which company has the “best” algorithm? In this course we will focus on the intuition of order notation. This topic will be covered again, in more depth, in later computer science courses. -- Definition: Algorithm A is order f(n) — denoted O(f(n)) — if constants k and n0 exist such that A requires no more than k * f(n) time units (operations) to solve a problem of size n ≥ n0. +- Definition: Algorithm A is order f(n) — denoted O(f(n)) — if constants k and n0 exist such that A requires no more than k * f(n) time units (operations) to solve a problem of size n ≥ n0. - For example, algorithms requiring 3n + 2, 5n − 3, and 14 + 17n operations are all O(n). This is because we can select values for k and n0 such that the definition above holds. (What values?) Likewise, algorithms requiring n2/10 + 15n − 3 and 10000 + 35n2 are all O(n2).