2011-11-25 96 views
3

我們已經在我們的代碼中聲明瞭如下所示的數組。數組要在棧本身上處理。 我們不與mallocnew更改靜態數組的大小

char a[20000]; 

現在有需要我們將其更改爲1800000(180kb),而不是20kb分配上堆的內存。 象下面這樣:

char a[1800000]; 

我們只是填充一些數據陣列。 這是一個有效的事情嗎?

我們可能會遇到什麼問題? 我只是擔心價值似乎太大。 有沒有更好的方法來繞過這個需求?

我正在solaris unix平臺上工作。

+0

你需要支持16位平臺嗎? –

+4

注:1800000個字節大約是1.7 MB,而不是180 KB – cbranch

+0

是的,你是right..i只是四捨五入它關閉但那不是overe這裏關注:) – Vijay

回答

0

我們只是用一些數據填充數組。這是 做的有效事情嗎?

是什麼,我們可能面臨的問題?

如果所有的數據訪問都是基於陣列前面的,並不是很多。如果從最終採取偏移或基於涉及尺寸的一些計算,則可能存在問題。

我只是擔心價值似乎太大。有沒有更好的方法來繞過這種需求?

有更好的方法,但不是因爲它的大小。 STL containers將是一個好主意。例如,可以在運行期間調整一個std::vector的大小,以滿足當前需要。

+0

如果你使用的是std :: vector,那麼你使用的是OP明確表示他們不想使用的動態內存,他們想要在堆棧(或靜態內存段)上分配數組。 std :: vector使用堆。 – Lundin

+0

@Lundin這不是問題的第一版。我用stl回答了原來的問題作爲一個建議。 –

+0

是的,在發表我的評論後,我注意到了這一點。 – Lundin

0

在大小無關的普通程序上,例如拍攝圖像時,它們可以保存mbs和mbs的數據,有時甚至是演出。如果你的程序運行在現代計算機上,我完全不擔心它的大小。

您應該考慮將該數據封裝到將被動態分配的對象中,因爲您可以使用realloc(如果使用c)增加運行時數據的大小。如果正確完成,這也將幫助您隱藏實施細節。

+1

堆棧大小和可執行文件大小 - 兩者都比堆分配更有限。 – Pubby

1

在此範圍內使用Malloc或新尺寸。總的來說,堆將更適合更大的分配。更容易調整大小。如果你的分配是在一個函數範圍內發生的,而這個函數會把它放在堆棧上,那麼情況尤其如此。如果這些是全局變量,那就不是那麼糟糕。但是,如果可能的話,我會堅持使用堆分配。

+2

爲什麼堆可能比數據段更好? –

+0

調整大小不是必需的,因爲我們相信,1.8MB足夠 – Vijay

+0

@MikeSeymour問題,缺乏任何'static'關鍵字甚至專門指出陣列「會在堆棧本身進行處理」。所以,堆是更適合這個尺寸的部分。 – Chad

2

這個數組真的是靜態的嗎?因爲沒有static關鍵字。

無論如何,在棧上創建如此大的數組並不是你真正應該做的。根據編譯器的不同,程序可能會崩潰,根據平臺和操作系統的不同,它也可能會崩潰。

如果你需要創建這麼大的數組,你應該在C++在C malloc()new做到這一點:

char *array = malloc(1800000 * sizeof(*array)); 

這是更便攜,更安全。另外,您無法調整堆疊中的數據大小。所以,使用堆。

HTH, CK

+0

這就是爲什麼我要求輸入關鍵字「static」。但是靜態存儲通常也是有限的,而堆只受RAM的限制。使用堆,盧克! :-) – ckruse

+0

OP很可能是指靜態存儲持續時間,在文件範圍內分配的每個變量都會得到。 – Lundin

5

在變量大小的顯着增加聲明諸如此可影響堆棧。我建議用std::vector替換它,這將創建堆中所需的大部分內存。畢竟,這被標記爲C++

+0

'static'不太可能在堆棧上實現。 –

+0

雖然這個問題意味着,它從發佈的代碼是不明確的情況下。如果這是在函數局部範圍內聲明的話,那麼可能會有後果,甚至會編譯。 – Chad

+0

反對轉向'std :: vector'的任何爭論?我認爲這是一個比使用'malloc/new'的原始指針更好的替代方案,因爲它的內存管理是由'vector'處理的。 – Chad

2

如果您確實是指「靜態」,並且這是適合現代平臺的平臺,那麼對於這種大小的靜態對象沒有問題。在32位平臺上,當您達到低千兆字節時,您將開始遇到困難;在64位平臺上,唯一的限制是可用的存儲容量。

但是,您也會說這是在堆棧上,這意味着它是自動的而不是靜態的。這可能是一個問題,尤其是在多線程程序中,因爲堆棧的大小是固定的。因此,您應該避免將大件物品放在堆疊上;如果合適的話使它們成爲靜態的,否則就是動態的 - 用C中的malloc創建它,並在C++中使用std::vector<char>

萬一您需要支持8位或16位平臺,您可能會發現創建大於64kb的對象是困難的或不可能的。在這種情況下,您可能需要將其分解爲更小的部分(假設您的內存超過64kb;否則,可以從磁帶或軟盤保存和加載頁面,但速度很慢)。

1

爲了澄清一些基本概念:

有關鍵字靜態的,並且有靜態存儲持續時間,這意味着該變量將持續整個程序的執行,並且只會有一個實例分配的變量。具有靜態存儲持續時間的對象存儲在RAM中的特定段中,通常稱爲.bss。聲明爲靜態或文件範圍(全局變量)的所有變量都具有靜態存儲持續時間。通過C/C++標準,保證靜態存儲時間的變量被初始化爲零。

堆棧是RAM中的一個動態部分,其中最常分配局部變量和函數參數。在堆棧中分配的變量通常被稱爲自動的,例如,讓編譯器自動處理這個變量並將其分配到最適合的位置,這可能在堆棧上,但也可以在CPU寄存器,緩存等中進行分配。 C/C++中的關鍵字auto,但不需要使用它:所有局部變量和參數默認爲自動。自動存儲的變量將包含垃圾值,除非明確初始化。

堆是RAM的另一個動態部分,只有當您通過malloc或new顯式分配變量時纔會使用堆。堆是您在討論動態內存分配時(通常也稱爲自由存儲管理)通常所指的內容。動態分配的變量將包含垃圾值,除非明確初始化。

在大多數計算機上,靜態段和堆只受RAM的數量限制,而堆棧的大小是固定的。在Unix這樣的多任務系統中,計算機中的每個進程都會有一個堆棧。我不確定有多大.bss或堆棧Unix/Solaris允許,我懷疑它將取決於計算機的年齡。舊的機器可能會在堆棧上分配1.7MB的問題。我對Unix機器知之甚少,但我懷疑這個建議是在堆上動態分配所有如此大量的數據(這就是你在PC上所做的)。

+0

稍微修改一下你的說明:當你說'具有靜態存儲持續時間的對象存儲在RAM中的一個特定的段中,通常被稱爲.bss'時,我會用'未初始化的'給前綴「對象」;初始化的對象通常放在另一個段中,而不是.bss。此外,當你說'具有靜態存儲持續時間的變量保證被初始化爲零的C/C++ standards',我建議編輯,爲'未初始化variables' – Dan

+0

@丹:我認爲用「未初始化」你參考使用靜態存儲的程序員未明確初始化的變量?我不太確定這對於所有編譯器來說都是如此。我想我已經看到了一些嵌入式的隱式和顯式初始化變量之間沒有任何區別,但將它們全部放在.bss中。 – Lundin