C 中字串駐留技術

2022-01-13 04:59:17 字數 1449 閱讀 5749

**:

msdn概念:公共語言執行庫通過維護乙個表來存放字串,該錶稱為拘留池,它包含程式中以程式設計方式宣告或建立的每個唯一的字串的乙個引用。因此,具有特定值的字串的例項在系統中只有乙個。

上面的概念不好理解,我們還是從基礎說起:

一、眾所周知,c#中的string是乙個引用型別,string物件存放在堆上,而不是在堆疊上的,因此,當把乙個字串變數賦給另乙個字串時,會得到記憶體中同乙個字串的2個引用。但是為什麼我們修改乙個字串的值,而另乙個字串的值不受影響呢?原來當我們把乙個字串的值賦給另乙個字串時候,就會建立乙個全新的string物件,就是說是分別指向堆中2個完全不同的位址空間。下面是乙個簡單例子:

static void main(string args)

結果是:

s1=charles

s2=charles

s1=charles chen change

s2=charles

也就是說,改變s1的值並沒有改變s2的值,這實際上是和引用型別是矛盾的。其實當s1="charles"時候,就在堆上分配了乙個string物件,在s2=s1時候,引用也指向這個引用,但是當s1的值發生變化的時候,而不是替換原來的值,實際上是在堆上新分配乙個記憶體空間,s2的值還是指向原來的物件,所以塔的值沒有發生變化。

二、然後我們看看下面的**塊:

string str1 = "charleschen";

string str2 = "charleschen";

當我們呼叫system.object.equals(str1,str2)時候,返回值是true,根據對上面的理解,按道理說是應該返回為false,str1和str2應該指向不同的記憶體空間才對。怎麼會返回為true呢?這裡就引入了"字串駐留技術"。

其實這裡clr使用了字串駐留技術,對於string str1="charleschen";string str2="charleschen";

當clr初始化時,會建立乙個內部的雜湊表(hash表),其中的鍵位字串,值為指向託管堆中字串的引用。剛開始,雜湊表為空,jit編譯器編譯方法時,會在雜湊表中查詢每乙個文字字串常量(這裡是"charleschen"),首先會查詢"charleschen",並且因為沒找到,編譯器會在託管堆中構造乙個全新的指向"charleschen"的物件引用,然後將"abc"字串和執行該物件的引用新增到雜湊表中去。

當string str2="charleschen"時候,由於前面已經在雜湊表中加了該"charleschen"字串,所以編譯器不會執行任何分配記憶體空間的操作。首先編譯器會在內部的雜湊表中查詢"charleschen",並且會找到,這樣指向先前建立的string物件的引用就會被找到,並且這裡str2就指向找到的那個引用。因此str1和str2就指向了記憶體中同乙個位址的引用。所以system.ojbect.equals(str1,str2)就返回為true了。

關於字串駐留

首先看幾個例子 示例1 static void main 示例2 static void main 示例3 public const string s1 abc static void main 示例4 public static string s1 abc static void main 示例1...

字串駐留備忘

下面是個人的練習 字串拘留練習 by mcjeremy 宣告s1時,拘留池中沒有該字串,因此將它放進去 放進去後,string.isintered s1 將返回該字串值 string s1 abc123 宣告s2時,由於拘留池中已經有該字串存在,因此不再分配記憶體 s2和s1將指向同乙個引用 str...

C 中字串的記憶體分配與駐留池

駐留池 是一張記錄了所有在 中使用字面量宣告的字串例項的引用的表,由clr維護 string s1 hello string s2 hello s2和s1的實際值都是 hello bool same object s1 object s2 這裡比較s1 s2是否引用了同乙個物件例項返回結果為true...