contributed by < akamayu-ouo
>
假設這個函式被用以下方式呼叫
因此 left
的初始值為 &X
,right
則為 Y
。
此時的關係
跳過迴圈後執行 *left = right;
,將 *left
(X
)設成 right
(A
的記憶體位置)。
回傳後的結果即為
進入函式時變數的關係如下:
因為對指標 A->B
等價於 (*A).B
,第 3 行可以改寫成
將 *left
、**left
以及 (**left).next
分別標注在圖上就是
更新 left
後它會指向 A.next
,此時 **left
即為 A
的下一個元素 B
。值得注意的是 X
的值維持不變,呼叫者仍有辦法以此找到 linked list 的起始點 A
(然而在函數中已無法得知 X
的值了)。
重複 left = &((**left).next);
,直到 *left
的值是 NULL 。此時 left
指向以 X
為首的 linked list 中最後一個元素的 next
變數。
跳出迴圈後執行 *left = right;
,將 B.next
設成 right
。
回傳後呼叫者看到的結果如下
用圖來解釋
範例測試程式中,若檢查發現 linked list 沒有正確排序,程式會馬上結束,但沒有釋放記憶體,造成 memory leak。
將範例程式中的 quicksort(&list)
那行註解掉後使用 valgrind --leak-check=full
測試的結果如下:
從輸出資訊(第 8 與 9 行)可以看出沒有被收回的記憶體是由函式 list_make_node_t
透過 malloc
配置。
我將測試程式修改如下以避免 memory leak。
根據 rand(3):
If no seed value is provided, the rand() function is automatically seeded with a value of 1.
也就是說,若在呼叫 rand()
之前沒有用 srand()
設定過種子, rand()
的行為會跟使用 1
作為種子一樣。因此範例程式才會總是產生出一樣的測試資料。
我改用 lrand48 來產生亂數。
All the functions work by generating a sequence of 48-bit integers, Xi, according to the linear congruential formula:
Xn+1 = (aXn + c) mod m, where n >= 0
The parameter m = 2^48, hence 48-bit integer arithmetic is performed. Unless lcong48() is called, a and c are given by:
a = 0x5DEECE66D
c = 0xB
To Be Continued …