具體的知識 && 知識在專案中的應用(以指標和記憶體的知識引出)

xumenger發表於2019-05-13

Delphi有兩種建立物件的方法

直接建立物件實體

比如建立一個執行緒有下面這樣兩種方式

begin
    TMyThread.Create;
end;

用變數(指標)儲存物件實體地址

var
    myTestThread: TMyThread;
begin
    myTestThread:= MyThread.Create;
end;

說明

第一種方式就是建立了一個執行緒,這個執行緒去執行,但是你卻沒有這個執行緒物件的指標,所以你不能去控制它,只能任由它去執行,如果能自己結束還好,但是如果是一個迴圈執行的執行緒,那麼就可能在那裡永遠執行下去,因為你在建立它的時候,沒有記錄這個執行緒物件的指標,所以你就沒辦法去控制它。其實對於執行緒還好,你可以設定它執行結束後自動釋放資源(FreeOnTerminate:= True),但是不管是執行緒類還是普通類,這樣建立之後就丟失了物件實體的地址,但是它還在記憶體中存在,這時候就只能是記憶體洩露。

第二種方式就是建立了一個執行緒,但是你記住了這個執行緒物件的指標,那麼你就可以在必要上的時候通過這個指標來控制它。

同理很多的類建立物件都是這樣的,第一種就相當於放飛了的鳥,你再也控制不了它了,而第二種就像是你在放風箏,可是那條線一直在你的手裡

擴充套件到到通過指標分配記憶體

程式碼示例

我們通過指標動態分配了記憶體之後,需要記住這個指標(該指標指向分配的記憶體),比如C/C++中的

int *pi;
pi =(int*) malloc(10* sizeof(int));

pi 就是用來記錄分配的記憶體的地址。在Delphi中

var
    pi: PInteger;
begin
    GetMem(p, sizeof(Integer)*10);
end;

這裡的pi 也是用來記錄分配的記憶體的地址。

就像上面兩種情況,如果在沒有釋放記憶體之前想要讓 pi 指向新的地址,這時候一定要建立新的指標首先儲存 pi的值(也就是儲存這塊記憶體的地址,比如 ptemp)

C/C++中

int* ptemp = pi;

Delphi中

var
    ptemp: PInteger;
begin
    ptemp:= pi;
end;

再去讓 pi 去指向新的地址,這樣就是為了不去丟失對這塊記憶體的控制,這樣pi 不再指向這塊記憶體,但是可以通過新的指向這塊記憶體的指標來釋放這塊記憶體,而不至於記憶體洩露,比如在C/C++和 Delphi中

C/C++中

free(ptemp);

Delphi中

FreeMem(ptemp);

為什麼要記住這塊記憶體的地址?

因為你之所以需要分配這塊記憶體,就是要使用這塊記憶體來儲存資料、對這裡的資料進行操作、以及最終去釋放這塊記憶體

只有你記錄這塊記憶體的地址,才可以通過指標來使用這塊記憶體,並且最終才能夠釋放這塊記憶體,否則分了記憶體確立馬丟失了這塊記憶體的地址,一方面無法使用這塊記憶體,另一方面無法釋放記憶體,最終導致記憶體洩露。

反思具體知識點在專案中的應用

很多東西因為要強調,所以會在部落格裡面專門的強調、專門寫強調它的程式碼、總結。但是在真正的專案中,往往是將所有的這個細節的小知識組合在一起使用,這些反覆強調的點都融合在專案的大量的程式碼中,並不會那麼明顯。

很多技術部落格只是將真實專案中的很多具體的技術點逐個拿出來單獨強調,但是在真實的專案開發中,往往是很多的各種各樣的技術點混在一起,根本沒有部落格裡面體現的那麼清楚。所以這個就是很多人覺得學習某個知識點很簡單,但是真到具體的開發中就感覺理不清楚的原因。

那麼一方面就是先將這些具體的知識點弄清楚,然後在具體的應用(以及研究原始碼)、設計的時候不要將所有的知識混在一起看待—確實是要將所有需要的知識點混在一起用,而是要先逐個的明白各個知識點怎麼在專案中應用,然後才能將它們結合在一起而不至於將自己弄迷糊

相關文章