2011-04-28 47 views
4

我的理解是,除了別的以外,還可以使用指針來允許您在需要時動態分配內存(並知道需要多少內存),而不是預先靜態分配數組。何時通過指針使用數組,或反之亦然

我很難確定何時它更好地節省動態分配的計算時間,並選擇較大的內存佔用量與較大的內存佔用量並使用一些計算時間來分配我只需要的內存。

有人可以在這個問題上談一點點?有任何一般規則可能有幫助嗎?

回答

1

你應該使用動態分配內存時:

  • 你不知道你會多少內存需要在編譯時
  • 的內存量運行時變化
  • 需要大量內存

你應該使用靜態分配內存時:

  • 你在編譯時間
  • 所需的內存量知道的大小是低

使用動態分配的內存需要系統的使用呼叫,這是當你編程問什麼操作系統。你有速度懲罰,因爲這個過程可能會失去給另一個過程的「處理時間」。操作系統需要做很多事情來完成呼叫。做一個詢問內存的系統調用是一個比寫入存儲在進程棧中的數組更重的過程。

+0

有沒有一種很好的方法來定義「所需內存量低」中的「低」。我對這個門檻在哪裏沒有很好的理解。 – Mark 2011-04-28 03:32:54

+0

這真的是我想問的問題的核心(但可能做得不好)。不過,我仍然對你可能考慮的低內存閾值感興趣。 – Mark 2011-04-28 03:42:19

+0

@Mark:如果你可以「存儲」你需要的所有內存,那麼堆棧有一個限制,可能是「低」。但請注意,所有函數都使用堆棧,因此如果許多函數使用內存,則可以在堆棧溢出中運行。有時使用動態內存更安全。這完全取決於程序需要多少內存以及哪個操作系統正在工作。沒有一個規則是大的或低的,它的正義經驗。 – anizzomc 2011-04-28 05:38:07

0

當您的數據是動態的時候使用動態容器,或者您需要從程序的不同區域傳遞數據。

1 - 動態數據 假設你有你的鄰居列表。他們在你的街道上建一座新房子,你必須增加一個人到名單上,但你只給15個鄰居分配了足夠的空間。這個動態內存將允許您增加該容器的大小。這不是真的如何運作。實際上,它會找到所需大小的一塊新內存,然後將舊容器複製過來。

或者另一個例子。假設你正在編寫一個跟蹤地址簿的程序。你的一個用戶有10個聯繫人。另一個用戶是一家公司,有5萬名員工需要存儲在這個地址簿中。您不想爲擁有十個聯繫人的用戶分配50000個空間,因此您可以精確分配您需要的數量。

2 - 傳遞數據 當您分配靜態數據時,它將被放置在堆棧上,然後超出範圍後將無法訪問。所以如果你調用一些生成你的數組的函數,然後把數組的內存地址傳回給調用者,你會得到一個運行時錯誤。這是因爲在該函數退出後,該數組超出了範圍,因此它彈出堆棧。

但是,如果您動態分配它,它就會在堆上,直到您釋放它或直到程序退出時纔會釋放。所以你可以只保留一個指向數組開頭的指針,並在整個程序中使用它,而不用擔心它會超出範圍,直到你想要。

+0

謝謝阿拉斯穆森,我很欣賞這種見解。我的興趣真的在你的第二個地址簿中。從數組切換到指針的閾值在哪裏?如果員工的最大數量是100,而不是50000,該怎麼辦?這只是一個判斷呼叫還是有規定? – Mark 2011-04-28 03:26:40

+0

我會一直這樣動態地做。對硬編碼的某些價值沒有意義,因爲那樣你就限制了你的程序,而你正在使用的內存不需要使用。那時,內存中唯一的限制是他們的硬件/設置,而不是你的程序。此外,我唯一一次使用靜態值的時候,數組始終是完全相同的大小。所以如果你存儲三維座標的位置,總是有三個座標,所以你可以使用一個有三個值的數組。沒有意義,使這種動態。 – 2011-04-28 03:28:11

0

數組只是連續的內存塊。當聲明的陣列,則指針

int foo[5]; 

foo(沒有索引)是一個指針,指向數組中的第一個元素。

foo[0] = 1; 
*foo = 1; 

那些做同樣的事情,因爲這樣做:

foo[1] = 2; 
*(foo + 1) = 2; 

當您使用您所創建的堆棧上int foo[5];陣列。這對當前函數是本地的,一旦從函數返回,它就不再有效。如果您malloc()內存,您要創建堆上的陣列(並有指向它的指針)

int *foo = malloc(sizeof(int) * 5); 
foo[0] = 1; 
*foo = 1; 

你必須自己管理這個內存,free()它,當你用它做:

free(foo); 
1

通常,當您知道要處理的數據的總大小或至少是最大數據大小時,您想使用數組。如果你真的不希望有巨大的變化 - 如果(例如)變量是10到20個項目,那麼最簡單的方法就是分配20個,不管這個變量是多少,並且用它來完成(除非每個項目都是真的是大)。

如果您提前瞭解數據的大小,或者(和重要的可能性)可能很容易處理太多計劃放入堆棧,動態分配變得更有用。動態分配的主要弱點是,如果你需要知道大小,你需要自己跟蹤它,這取決於你在完成任務時是否釋放內存。 C中的許多問題(特別是困難,煩人的問題)可以歸結爲在釋放內存後使用內存,或者在完成後忘記釋放內存。

0

雖然這個問題有一個公認的答案。讓我談談一個稍微不同的事情。在C中,有時你可以使用一個大小在運行時確定的數組。例如:

void foo (int a[], int n) { 
    int buf[n]; 
    /* do something with buf[] */ 
} 

這種類型的數組在堆棧中分配並且大小可變。與做malloc的區別在於你不需要free()的內存;當函數調用存在時,這被照顧。當然這也意味着你可能不能返回數組的地址。

相關問題