2022q1 Homework1 (lab0)
contributed by < Shawn5141
>
Homework Requirement
Quiz1 Answer and Discussion
Function Requirement
queue_new:
Create a new, empty queue. Because it's empty queue, initilize empty list will suffice the requirement here.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
After allocating queue memory (element_t), use linux/list.h macro INIT_LIST_HEAD to initialize list_head member element.
- Time complexity:
- Space complexity:
queue_free:
Free all storage used by a queue.
- Use list_for_each_safe to iterate through queue and call list_del to remove list entry. Comparison for list_for_each vs list_for_each_safe. If there is char array in element_t, those memory also need bo be freed. After char array is cleaned, element would be freed entirely.
- Time complexity:
- Space complexity:
queue_insert_head
Attempt to insert a new element at the head of the queue (LIFO discipline).
- Allocate memory for element_t and char array through self-defined function q_ele_new (described latter).
- Use linux list_add macr to add newly allocated element's list_head to head of list.
- Time complexity:
- Space complexity:
queue_insert_tail
Attempt to insert a new element at the tail of the queue (FIFO discipline).
1. Allocate memory for element_t and char array through self-defined function q_ele_new (described latter).
2. Use linux list_add_tail macr to add newly allocated element's list_head to end of list.
- Time complexity:
- Space complexity:
q_remove_head
Refering to self-defined function __q_remove
. By providing pointer to first list_head element. It would
- Retrieve first element using list_entry.
- Utilize list_del to remove first element's list_head without delete it.
q_remove_tail
Refering to self-defined function __q_remove
. By providing pointer to last list_head element. It would
- Retrieve last element using list_entry.
- Utilize list_del to remove first element's list_head without deleting it.
q_delete_mid
Use slow-fast pointer technique to find out middle point (Refers to helper function __q_ele_mid
)
q_delete_dup
-
Initilize left and right pointer.
-
Proceed to while loop when both left and right value are same
- Assign right pointer to tmp pointer
- Move right pointer to it's next
- Delete right pointer
-
If dup_flag is on, delete left pointer
-
Move right pointer to it's next and terminate while loop when right pointer is point to head
-
On the other hand, if there is no duplicate element in sorted list, the left pointer and right pointer will just continue proceed to next til right pointer point to head.
Shorten the above code snip by effective techniques.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
jserv
Verson2:
Still require dup_flag. But release left pointer instead of right one. Need to come up with more effective techniques latter.
q_swap
Move node in front of fack node and proceed node two step further
q_reverse
- Create prev_node and next_node pointer pointing to head.
- Create curr_node pointer pointing to next list_head in list.
- Iterate through list while curr_node is not equal to head
- Assign next_node as next list_head of curr_node.
- Make curr_node pointing it's next pointer to prev_node.
- Make prev_node point it's prev pointer to curr_node.
- Let head point it's next to curr_node while point curr_node's prev to head. So that the cycle is closed.
- Make head eqaul to prev_node.
q_sort
Developing about iterative merge sort:
Problem:
- How to intialize pointer to list_head array with default value of empty head.
- Unable to figure out how to do merge circular sorted list. So decide to turn circular list into normal linked list and convert it back after sorting.
q_shuffle
Pusedo code
This algorithm create true randomness given to the fact that the probablity of chosen number place to each position are same.
For example, if we randomly pick one position (let's say 3rd position) in array [0,1,2,3,4] to swap with the last position. The probablity is 1/5. And the array became [0,1,2,4,3]. Then in next round, as we choose from 1 to 3 (n-1), the probablity are still (4/5)*(1/4)=1/5 no matter which position we choose to swap the last element with.
Add command to qtest
I found this macro ADD_COMMAND added 3 weeks ago and this is align with this article Preprocessor operators.
- Stringizing operator (#): 用來將引數變成一個字串
- Charizing operator (#@): 用來將引數變成一個字元
- Token-pasting operator (##): 用來拼接引數
- Add shuffle using ADD_COMMAND
I need to think about a way to declare q_shuffle function since I can't modify queue.h.
Swap function for any given two node.
__q_swap
- Get l2 previous node (l2_prev) and remove l2 from list.
- Replace l1 by l2.
- Check if l1 used to be l2->prev. We can place l1 in next node of l2, so assign l2_prev as l2.
- Use list_add to add l1 as next node of l2_prev.
Create random in range
- Since void srand( unsigned seed ) is called in qtest line 967, we don't need to repeatedly called it.
Seeds the pseudo-random number generator used by rand() with the value seed. Note: The pseudo-random number generator should only be seeded once, before any calls to rand(), and the start of the program. It should not be repeatedly seeded, or reseeded every time you wish to generate a new batch of pseudo-random numbers.
- Call rand() function. Need to convert it into integer.
Use list_head pointer array to store pointer
- Using array to store pointer can greatly reduce time for traversing.
Final solution
- Create array pointer and store each pionter into it (line 11)
- Apply Fisher–Yates algorithm and call __q_swap to swap two pointer's position in list.
- swap chosen pointer in array with pointer in last array position.
__q_ele_new
- Allocate new node and let pointer to pointer to element_t point to newly allocated address of element_t with char array initilized.
- Time complexity:
- Space complexity:
__q_ele_remove
- Created generic
__q_remove
function called by q_remove_head and q_remove_tail. It would remove the element from list and copy out element char array to specifed buffer (sp) with given length (bufsize).
AddressSanitizer
-
Feature
- 對堆、棧和全域性記憶體的訪問越界(堆緩衝區溢位,棧緩衝區溢位,和全域性緩衝區溢位)
- UAP(Use-after-free,懸掛指標的解引用,或者說野指標)
- Use-after-return(無效的棧上記憶體,執行時標記 ASAN_OPTIONS=detect_stack_use_after_return=1)
- Use-After-Scope (作用域外訪問,clang標記-fsanitize-address-use-after-scope)
- 記憶體的重複釋放 (double-free)
- 初始化順序的BUG
- 記憶體洩漏 (memory leak)
-
How to use: