《C陷阱與缺陷》 緩衝輸出和記憶體分配

2021-07-30 03:55:06 字數 1160 閱讀 4053

程式輸出有兩種方式:一種是即時處理方式,另一種是先暫存起來,然後再大塊寫入的方式,前者往往造成較高的系統負擔。

因此,c語言實現通常都允許程式設計師進行實際的寫操作之前控制產生的輸出資料量。

這種控制能力一般是通過庫函式 setbuf 實現的。如果 buf 是乙個大小適當的字元陣列,那麼:

setbuf(stdout,buf);
語句將通知輸入/輸出庫,所有寫入到 stdout 的輸出都應該使用 buf 作為輸出緩衝區,知道 buf 緩衝區被填滿或者程式設計師直接呼叫fflush(注:對於由寫操作開啟的檔案,呼叫 fflush 將導致輸出緩衝區的內容被實際的寫入該檔案),buf 緩衝區中的內容才實際寫入到 stdout 中。緩衝區的大小由系統標頭檔案 stdio.h 中的bufsiz 定義。

下面的程式的作用是把標準輸入的內容複製到標準輸出中,演示了 setbuf 庫函式最顯而易見的用法:

#include 

int main()

return

0;}

遺憾的是,這個程式是錯誤的,僅僅是因為乙個細微的原因。程式中對庫函式 setbuf 的呼叫,通知了輸入/輸出庫所有字元的標準輸出應該首先快取在 buf 中。要找到問題出自何處,我們不妨思考一下buf緩衝區最後一次被清空是在什麼時候?答案是在 main 函式結束之後,作為程式交回控制給作業系統之前c執行時庫所必須進行的清理工作的一部分。但是,在此之前 buf 字元陣列已經被釋放

要避免這種型別的錯誤的辦法是:讓緩衝陣列成為靜態陣列,既可以直接顯式宣告 buf 為靜態:

static

char buf[bufsiz];

也可以把 buf 宣告完全移到 main 函式之外。

第二種方法是動態分配緩衝區,在程式中並不主動釋放該緩衝區,這樣c執行是庫進行清理工作時就不會發生緩衝區已經被釋放的情況。

char *malloc();

setbuf(stdout, malloc(bufsize));

這裡其實並不需要檢查 malloc 函式呼叫是否成功,如果 malloc 函式呼叫失敗將會返回乙個 null 指標,setbuf 函式的第二個引數可以為null,此時標準庫不需要進行緩衝。這種情況下程式仍然能夠工作,只不過速度慢一些而已。

緩衝輸出與記憶體分配(C語言陷阱)

程式處理方式有兩種,一種是即使處理,另一種是暫時存期再大塊寫入的方式,前者往往造成比較大的系統負擔,因此c語言往往允許程式猿進行實際的寫操作之前控制生產的資料量 這種控制一般由庫函式setbuf 來實現,如果buf是個大小合適的陣列,則 setbuf stdout buf 語句將通知輸入 輸出庫,所...

緩衝輸出與記憶體分配

程式輸出有兩種方式 一種是即時處理方式,另一種是先暫時存起來,然後再大塊寫入的方 式,前者往往造成較高的系統負擔。因此,c語言實現通常都允許程式設計師進行實際的寫操作 之前控制產生的輸出資料量。setbuf stdout,buf 此語句通知輸入輸出庫,所有寫入到 stdout 的輸出都應該使用 bu...

緩衝輸出和記憶體分配

程式輸出有兩種方式 一種是即時處理方式,另一種是先暫存起來,然後再大塊寫入的方式,前者往往造成較高的系統負擔。因此,c語言實現通常都允許程式設計師進行實際的寫操作之前控制產生的輸出資料量。這種控制能力一般是通過庫函式setbuf實現的。如果buf是乙個大小適當的字元陣列,那麼 setbuf stdo...