2012-12-15 210 views
1

據我所知,malloc函數接受一個變量並按照問題分配內存。在這種情況下,它會要求編譯器準備內存以適應二十個雙變量的等值。我的方式正確理解它,爲什麼它必須被使用?爲什麼必須使用malloc?

double *q; 

q=(double *)malloc(20*sizeof(double)); 

for (i=0;i<20; i++) 
{ 
    *(q+i)= (double) rand(); 
} 
+2

的'malloc'功能不「帶可變」。它將需要的內存大小作爲參數,並作爲結果返回新分配的(未分配的)內存指針區域。 –

+1

無需強制轉換的ANSI/ISO C的malloc,爲更多閱讀:HTTP://c-faq.com/malloc/cast。html – Omkant

+0

typecasting malloc意味着這個......'(double *)'......正確嗎?我們不再添加這個,因爲新版本的C可以認識到我們已經在處理'double'而不是'char'了? – EngGenie

回答

4

它被用來在運行時而不是編譯時分配內存。因此,如果您的數據數組基於來自用戶,數據庫,文件等的某種輸入,那麼一旦知道所需大小,就必須使用malloc

變量q是一個指針,意味着它在內存中存儲地址。 malloc要求系統創建一段存儲器並返回存儲在q中的該段存儲器的地址。因此q指向您請求的內存的起始位置。

必須小心,不要無意中更改q。舉例來說,如果你這樣做:

q = (double *)malloc(20*sizeof(double)); 
q = (double *)malloc(10*sizeof(double)); 

您將無法訪問的20 double的第一部分,介紹了內存泄漏。

+0

謝謝你的回答,內存泄漏! – EngGenie

1

在您例如,你可以宣佈double q[20];沒有malloc和它的工作。

malloc是一種標準的方式來獲得動態分配的內存(malloc通常高於低級別的存儲採集原語建立像mmap在Linux上)。

您希望獲得動態分配的內存資源,尤其是當分配的東西(這裏是您的指針q)的大小取決於運行時參數(例如取決於輸入)時。不好的選擇是靜態分配所有數據,但是數據的靜態大小是一個強大的內置限制,你不喜歡這樣做。

動態資源分配,使您可以在一個便宜的平板電腦上運行同一程序(使用的RAM億字節)和昂貴的超級計算機(與RAM兆兆字節)。您可以分配不同大小的數據。

不要忘記測試的malloc的結果;它可以通過返回NULL來失敗。最起碼,代碼:

int* q = malloc (10*sizeof(int)); 
if (!q) { 
    perror("q allocation failed"); 
    exit(EXIT_FAILURE); 
}; 

總是初始化malloc -ed內存(你能喜歡使用calloc其歸零​​分配的內存)。

不要忘了以後freemalloc -ed內存。在Linux上,瞭解如何使用valgrind。害怕memory leaksdangling pointers。認識到某些數據的活躍性是整個程序的非模塊化屬性。閱讀關於garbage collection!,並考慮可能使用Boehm's conservative garbage collector(通過調用GC_malloc而不是malloc)。

+0

優秀的答案,正是我在尋找的謝謝!像這樣測試'malloc'的結果嗎? ... if(p == NULL) printf(「無法爲p \ n分配請求的內存」); }' – EngGenie

+0

更好地使用'perror'來顯示失敗原因,通過'errno' –

+0

似乎你在我的問題被一個答案問了之前,呃! – EngGenie

0

您可以使用malloc()C中動態分配內存。 (分配在run time內存) 你使用它,因爲有時你不知道當你寫你的程序,你會使用多少內存。 當您知道在編譯時數組將保存多少元素時,您不必使用它。

另一個重要的事情要注意,如果你想從一個函數返回一個數組,你會想返回沒有堆棧定義功能裏的數組。相反,你要動態分配一個數組(在),並返回一個指向該塊:

int *returnArray(int n) 
{ 
    int i; 
    int *arr = (int *)malloc(sizeof(int) * n); 
    if (arr == NULL) 
    { 
     return NULL; 
    } 

    //... 
    //fill the array or manipulate it 
    //... 

    return arr; //return the pointer 
} 
+0

向下投票:我認爲如果函數的調用者提供了內存,它會更好。 – hendrik

+0

是的,函數的調用者通常不關心函數中的事情如何完成。但提供應該填充的內存的風格仍然更好。 – hendrik

6

您不必使用malloc()時:

  1. 的大小在編譯時已知,如你的例子。
  2. 您正在使用帶有VLA(可變長度陣列)支持的C99或C2011。

請注意,malloc()在運行時分配內存,而不是在編譯時。編譯器只涉及它確保調用正確函數的程度;這是分配的malloc()

你的例子提到'十個整數的等價'。 20 double很少佔據與10 int相同的空間。通常,10 double將佔據與20 int(當sizeof(int) == 4sizeof(double) == 8,這是非常常見的設置)相同的空間。

+0

啊,我似乎混淆了筆記中的指針!我的意思是說它會分配內存20'雙'。謝謝你的出色答案! – EngGenie

+0

@EngGenie:如果你看到一個答案可以回答你的問題,那麼*接受*它通常是一個好主意。點擊其左側的灰色刻度標記。這給答案者一些額外的點,併爲讀取你的問題的其他人提供提示。 – fuz

1

正如其他人所說,malloc用於分配內存。注意malloc會從堆中分配內存很重要,因此內存一直持續到free'd。否則,如果沒有malloc,聲明類似double vals[20]將在堆棧上分配內存。當您退出該功能時,該內存將從堆棧中彈出。

因此,例如,說你是在一個函數,你不關心價值的持久性。那麼下面將是合適的:

void some_function() { 
    double vals[20]; 
    for(int i = 0; i < 20; i++) { 
     vals[i] = (double)rand(); 
    } 
} 

現在,如果你有一些全球性的結構或一些存儲數據,具有壽命比只是功能的時間越長,那麼使用malloc分配內存從堆(或者,您可以將其聲明爲全局變量,並且會爲您預先分配內存)。

3

當你使用malloc你問系統「嘿,我想要這麼多字節的內存」,然後他會說「對不起,我全部出來」或「好的!這是一個內存地址你想要的,不要失去它「。

將大數據集放在堆中(其中malloc從中獲取內存)和一個指向堆棧內存儲器(執行代碼)的指針通常是一個好主意。在內存有限的嵌入式平臺上,這一點變得更加重要。您必須決定如何分配堆棧和堆之間的物理內存。太多的堆棧,你不能動態分配太多的內存。太少的堆棧,你可以函數調用你的路右出它(又稱堆棧溢出:P)

相關問題