變長字串的記憶體管理

2021-06-05 16:46:32 字數 1459 閱讀 8802

方法1:靜態記憶體

這裡有乙個方法來實現幫助函式:

const char *

get_string()

複製**

這個方法的好處是比較簡單,但是它也有很多嚴重的缺點。

返回的字串可能比你期望的要長。無論你指定buf什麼樣的長度,它仍然可能太小。如果實際的字串太長,你或者超出陣列的範圍最終導致**悲慘的失敗,或者必須擅自截斷那個字串。

對於較短的字串,這個函式因為buf陣列的大部分沒有用到而浪費了記憶體。每一次get_string呼叫覆蓋了前一次呼叫的結果。如果呼叫者想保留前一次呼叫的字串,在再一次呼叫這個函式之前,他必須把上一次的字串做乙份拷貝。

這個函式不是可重入的。如果多個執行緒同時呼叫get_string,乙個執行緒會覆蓋另乙個執行緒的結果。

方法2:靜態指標指向的動態記憶體

這是第二種實現get_string函式的方法:

const char *

get_string()

rlen += size_of_block;

}return result;}

複製**

這個方法使用指向動態記憶體的乙個靜態指標,不斷地增長緩衝區用來容納資料。使用動態記憶體除去了字串任意長度的限制,當然另一方面它

仍然有前乙個方法的問題:每一次呼叫仍然覆蓋前一次呼叫的結果,函式不是可重入的。這個版本也浪費了相當大數量的記憶體,因為它永遠消

耗最壞情況下的記憶體數量(它曾經讀取的最長字串的長度)。

方法3:呼叫者分配的記憶體

在這個方法中,我們讓呼叫者負責提供容納字串的記憶體。

size_t

get_string(char * result, size_t rsize)

複製**

這個就是被unix作業系統的read系統呼叫所採納的方法。它解決了大部分的問題。包括它是可重入的,不會記憶體溢位,不會擅自的截斷資料。

(潛在的浪費記憶體的數量在呼叫者的控制之下。)

弊端在於如果字串比提供的緩衝區更長,呼叫者必需保持呼叫直到所有的資料被讀取。(如果我們假定資料來源隱含在呼叫的執行緒中,那麼多

個執行緒的重複呼叫是可重入的。)

方法4:返回指標指向的動態記憶體

在這個方法中,get_string動態的分配乙個足夠大的緩衝區來容納結果,並返回乙個指向緩衝區的指標。

char *

get_string()

return result;}

複製**

這個幾乎和第二個方法一樣(它們之間的區別是get_string沒有使用靜態資料)。它幾乎解決了所有的問題:函式是可重入的,對於結果字元

串沒有乙個隱含的大小限制。對於長字串並不要求多次的函式呼叫(但是動態分配增加了一些開銷)。

這個方法的主要缺點是它讓呼叫者負責釋放分配的記憶體:

/* ... */

/* bad news, forgot to deallocate last result! */

複製**

可變長字串

目錄stringbuilder 其他可變長字串,jdk1.0提供,執行效率慢,執行緒安全字串緩衝區 執行緒安全的可變字串 字串行 字串 如果字串需要頻繁修改,可用stringbuffer構造方法stringbuffer 初始容量為16個字元 stringbuffer int capacity 構造乙...

記憶體管理屬性字串

分類 ios開發 2014 05 26 14 36 726人閱讀收藏 舉報 assign 指定setter方法用簡單的賦值,這是預設操作。你可以對標量型別 如int 使用這個屬性。你可以想象乙個float,它不是乙個物件,所以它不能retain copy。assign指定setter方法用簡單的賦值...

struct 封裝變長字串

使用struct,可以非常方便的處理二進位制資料,將常用的int,string等型別的資料轉成二進位制資料,它有兩個重要函式,乙個是pack,乙個是unpack 先看一張表 struct中支援的格式如下表 format c type python 位元組數x pad byte no value1c ...