簡體   English   中英

堆vs堆棧vs bss部分

[英]Heap vs stack vs bss section

還有什么更好的地方來存儲具有恆定預定義大小的運行時數據(如緩沖區):堆(malloc),堆棧(例如,函數內部的char buf[BUFSIZE] )或bss節(全局區域中的char buf[BUFSIZE] )?

這取決於您要對緩沖區執行的操作。

通常應避免使用全局變量,您必須非常小心,以免落在它們帶來的問題上。

如果僅在一個函數中需要緩沖區並且BUFSIZE不太大(最大幾個KB),則可以將其設置為本地。 但是,請注意總堆棧使用情況,因為嵌套調用會累加。 僅當要在兩次調用之間保留值時才需要靜態局部,從而有效地使其成為具有局部范圍的全局變量。 但是當您使用多線程或要使用遞歸時,它將使您頭痛。

如果在函數調用之間使用了緩沖區,或者BUFSIZE很大,則使用malloc()/ free()。 如果經常調用該函數,則最好在函數外部分配一次,執行所有函數調用,然后釋放它,而不是為每個函數調用分配並釋放另一個緩沖區。 但這接近於過早的優化,因為它不必要地將函數的內部結構與外部調用程序耦合在一起。

從總體上看,當程序增長時,您想給它更多的結構並明確定義職責,尤其是。 進行內存處理,否則您最終會迷路。 該緩沖區是具有特定任務的特定模塊的工作細節。 一種典型的方法是使用結構以OOP方式組織數據,並使用創建和銷毀功能來分配和釋放此類對象。 緩沖區然后可以是該結構的一部分。

struct s_foo
{
    char buf[BUFSIZE];
    ...
};

struct s_foo *foo_create (...);
void foo_destroy (struct s_foo *foo);
void foo_action (struct s_foo *foo);

這使您可以並行使用任意數量的foo,每個foo都有自己的緩沖區,彼此獨立。 另外,緩沖區內容在兩次調用之間保持不變,而不會產生靜態變量的麻煩。

在這種情況下,如果未在函數之間共享緩沖區,則IMO最佳選擇將是局部靜態變量:

void func(...) {
    static char buf[BUFSIZE];
}

這樣可以避免重復分配/取消分配和名稱空間混亂。

編輯

該解決方案不是線程安全的,但全局變量也不是。

您需要一個靜態變量,該變量在加載時分配,並且在程序的整個生命周期中一直保持不變。 因此,選擇三,即所謂的“ bss”部分。

顯然,由於大小有限,堆已用完。 我也不會選擇靜態變量,因為它們不是可重入的,並且會給遞歸帶來嚴重破壞。 因此,將其放入堆棧框架中。

void f(...) {
    char buf[BUFSIZE];
}

順便說一句,除非絕對必要,否則避免靜電或全局變量的一種良好做法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM