我寫程式的原則是這樣,
除非系統相依的功能,否則在非必要的情況下,我盡可能的使用標準函式庫裡面的東西,
而不是_GNU_SOURCE之類的實作。
今天review了另一個人的code,
說實在那code寫得滿愚蠢的,至於有多愚蠢容後解釋。
他想要做這樣的動作:
先將一段未知長度的資料(可能非常非常的長,
而大部份的case那段資料的長度都很短,只有在鮮少的機會出現極長的資料,
所以如果我們每次都allocate一塊大記憶體來用,這樣是不經濟的)轉成一個長字串,
然後再將該長字串透過UNIX Socket傳給另一個程式。
這樣的動作其實有很好的函式可以用像是dprintf或是vdprintf,
但是在uclibc的函作當中,這樣寫出去的東西可能是"分兩次"寫出去的,
而大部份的人寫程式的習慣也是一來一往的通訊而已,不會分段收。
所以這樣的寫法在很多case上是有問題,結論我也不可以用dprintf。
然後我接手的那個程式很妙,他會malloc(512),至於為什麼要用malloc一個固定長度我一點也不懂,
於是他在處理超過512個byte的結果時就出問題了,程式就當掉…
事實在linux的libc實作有很多方便的函式可以用,但是卻不一定標準,例如aprintf。
我看了一下,後來則是用了vsnprintf,第一它可以限制住讓程式不會寫過頭造成SIGSEGV,
第二則是它回傳值是「他真正需要的長度」。
所以我就寫了一個這樣的程式碼,來對付超級長的字串。
int len = 256;
int retl = 0;
unsigned char* ptr = NULL;
do {
if (ptr != NULL) {
free(ptr);
len = retl;
}
ptr = malloc(len);
if (ptr) {
memset(ptr, 0, len);
...
retl = vsnprintf(ptr, len, ..., ...);
}
/* if retl == len, the reuslt is still lack of the last char. */
} while (retl >= len);
...
free(ptr);
雖然當得我莫名奇妙的,但是解決的方法還算滿有意思的。
請先 登入 以發表留言。