先來段**
type
mystring = ansistring;
pmychar = pansichar;
procedure tform2.button2click(sender: tobject);
varp: pmychar;
s, s2: mystring;
begin
self.caption := '
frmtest
'; //7位的字串
p := getcaption;
s2 := p; //這是時候s2 為frmtes
showmessage(s2); //*****顯示出來為frmtes
end;
function tform2.getcaption: pmychar;
vars1, s2: mystring;
begin
s2 := mystring(self.caption);
result := pmychar(mystring(s2));
end;
研究說明(代表個人意見)(xe下面測試)
function tform2.getcaption: pmychar;
vars1: mystring;
begin
s1 := mystring(self.caption); 原始碼得知,是獲取了一塊臨時的空間(a1)
//a1(integer(s1))
i:= stringrefcount(s1); //i=1
result := pmychar(mystring(s1)); //result指標指向的為(a1)的空間
//integer(@result^) = a1(integer(s1)) 是指向同一塊空間
i:= stringrefcount(s1); //i=1
end;
//函式返回後s1因為是區域性變數 s1的引用計數為0,integer(s1)的空間被標誌為可以覆蓋
//返回的為指標,不增加s1的引用計數
procedure tform2.button2click(sender: tobject);
varp: pmychar;
s, s2: mystring;
begin
self.caption := '
frmtest
';p := getcaption; //實際上p指向的那塊位址被標註為可以覆蓋,隨時都有可能被覆蓋,是很危險的
//integer(@p^) = getcaption內部給s1分配的那塊空間位址
s2 := p; //導致丟掉了字元..
//因為p指向的記憶體是可以被覆蓋的,s2分配的位址可能和p指向的位址是一樣的,導致丟掉了字元..
//integer(s2) 可能= integer(@p^) 測試是發現都一樣
//下面操作(setlength)同樣也會一樣結果,s2占用的和p占用的同樣大小(或者小)。
//這樣導致了s2分配的空間可能和p記憶體一樣
//如果7改成較大的數就正常
// setlength(s2, 7);
// strcopy(pmychar(s2), p);
showmessage(s2); //錯誤
end;
解決方案(1)
將s1定義為內成員變數,這樣當getcaption執行完後那塊空間不會被標準為可讀寫
function tform2.getcaption2: pmychar;
begin
fmycaption := mystring(self.caption); 原始碼得知,是獲取了一塊臨時的空間(a1)
//a1(integer(fmycaption))
i:= stringrefcount(fmycaption); //i=1
result := pmychar(mystring(fmycaption)); //result指標指向的為(a1)的空間
//integer(@result^) = a1(integer(fmycaption)) 是指向同一塊空間
i:= stringrefcount(fmycaption); //i=1
end;
//執行完後fmycaption不是臨時變數,指向的位址不可以被覆蓋
procedure tform2.btngetcaption2click(sender: tobject);
varp: pmychar;
s, s2: mystring;
begin
self.caption := '
frmtest
';p := getcaption2; //實際上p指向的那塊位址和fmycaption的位址是一樣的
//integer(@p^) = getcaption2內部給fmycaption分配的那塊空間位址是一樣
s2 := p;
//因為p指向的記憶體是不可以被覆蓋的,s2分配的位址不可可能和p指向的位址是一樣的,這樣做是安全的
//integer(s2) <> integer(@p^)
i:= stringrefcount(s2); //i=1 新的記憶體
showmessage(s2); //正確
end;
區域性變數
function tform2.getcaption2: pmychar;
vars1: mystring;
begin
s1 := '
frmtest
'i:= stringrefcount(s1); //i=-1 常量位址指向空間不可被覆蓋
//uniquestring(s1);
//i:= stringrefcount(s1); //i=1 s1又變成臨時的,函式返回後s1指向的位址不再安全
result=pmychar(s1)
end;
引用計數與智慧型指標
c 沒有完善的gc機制,直到c 11才在stl中正式引入了智慧型指標。出現在庫中說明智慧型指標不是語言特性。c 智慧型指標實現了部分自動記憶體管理的目的。引用計數是使用資源管理函式 構造析構複製等函式 和作用域原理實現的。每塊動態分配的記憶體 堆記憶體 都維護乙個相應的計數器,來記錄指向該記憶體的變...
Python中的引用計數
為了跟蹤記錄已經分配的記憶體,python 做法類似於撲克牌遊戲中的記牌手法。乙個物件在建立時被加上乙個引用。乙個內部的引用記錄變數將跟蹤記錄下每個物件有多少個引用。乙個物件被建立和被賦值時,它的初始引用計數為 1。物件新的引用也叫別名 alias 發生在 其他變數也被賦值到同乙個物件 物件作為呼叫...
引用計數器 與 記憶體管理
一 引用計數器的基本操作 1.方法的基本使用 1 retain 計數器 1,會返回物件本身 2 release 計數器 1,沒有返回值 3 retaincount 獲取當前的計數器的值 4 dealloc 當乙個person物件被 的時候,就會自動呼叫這個方法 void dealloc 2.概念 1...