2014-05-13 216 views
1

在我整個CS生涯中忽略了C後,我決定給它看一看!爲什麼我們需要calloc(或malloc)?

當初始化變量,我們可以有:

int b = 0; 

這初始化b,爲其分配內存,我們可以在以後用

b = 2; 

更新如果需要的話。

所以,原諒我這個可笑的「小白」的問題,但爲什麼我們需要一個像電話:

double *b = (double *) calloc(n, sizeof(double)); 
初始化變量將已經分配的空間,它的時候

爲什麼我們不只是做

double b = 0; 
b* = b.addressOf(b) //or some similar construct. 

什麼用的呢?

我試過谷歌搜索這沒有用,所以請原諒我 - 很遺憾*谷歌是一個通配符,所以相關的結果很難找到。

+0

不同的是靜態分配(堆棧)和動態分配(在HEAP) –

+1

閱讀這一個:http://stackoverflow.com/questions/8385322/difference-between-static-memory-分配和動態內存分配 – pablochan

+1

另外一個原因是你並不總是事先知道你需要多少數據。'double d [1000];'如果你只需要幾個元素是非常浪費的,如果你需要超過1000個元素是很危險的。如果你可以在運行時確定你需要多少,你可以使內存使用更有效率。 – mah

回答

2

當前上下文中聲明的變量在上下文結束時結束其生命週期。

分配內存爲您提供存儲更長壽命變量的空間。

例如,

double *foo() { 
    double d; 
    return &d; 
} 

void bar() { 
    double *d = foo(); 
    *d = 0.0; 
} 

將嘗試訪問不再存在的變量,因爲它的壽命是foo功能。

C和C++不會跟蹤對象。指針只指向對象,但不擴展對象的生存期,因此即使它不是NULL,指針也是無效的。

然而,這是有效的:

double *foo() { 
    return (double *)malloc(sizeof(double)); 
} 

void bar() { 
    double *d = foo(); 
    *d = 0.0; 
} 

這將分配內存爲double,指針返回到存儲,這仍然有效,直到明確恢復使用free功能池。不將它返回到池會造成內存泄漏。

0

除非我完全錯誤,否則在C中,callocmalloc是實現動態數據結構的唯一可能性。

+2

方式無關緊要;問題不在於爲什麼要使用'calloc()'而不是其他一些動態分配,這就是爲什麼要使用動態分配。 – mah

0

當談到關於可變分配,你可以不喜歡它:

  1. 靜態堆棧,簡單地說:int a = 10。這些變量最可能與一些使用它們的代碼一起定義在堆棧上(這就是爲什麼在沒有正確檢查boudadries的情況下寫入棧中聲明的數組可能很危險的原因。變量也有一個範圍:函數範圍,全局範圍和其他範圍(例如if-else的if-branch)。它們使用起來很快,但是它們或多或少都是......靜態的,他們有很大的優勢,你不需要清理它們。它們由應用程序自動清理。然而他們有很大的缺點。堆棧空間比堆空間更有限。所以你只能使用適度大小的變量(不要直接從字面上理解,而應該研究一下你的操作系統允許的內容,64KB對於每個人來說都是不夠的:))。
  2. 在堆上動態地使用calloc()或其他一些內存分配函數。這些變量在一個稱爲堆或動態內存的區域中聲明。這些變量將一直存在,直到使用它們的應用程序退出(在這種情況下(現代)OS通常會將內存回收到自身),或者它們是freed,使用free()。你總是應該釋放內存以避免內存泄漏。動態內存的優點是(在現代操作系統上)可尋址內存遠大於分配給堆棧空間的大小,因此可以擁有更多,更大,更大的結構和陣列。
0

作用域是代碼中可以訪問變量的區域或部分。可以有

  1. 文件範圍
  2. 功能範圍
  3. 塊作用域
  4. 計劃範圍
  5. 原型範圍

#include<stdio.h> 

void function1() 
{ 
    printf("In function1\n"); 
} 

static void function2() 
{ 
    printf("In function2\n"); 
    { 
     int i = 100; 
Label1: 
     printf("The value of i =%d\n",i); 
     i++; 
     if(i<105) 
     goto Label1; 
    } 
} 

void function3(int x, int y); 

int main(void) 
{ 
    function1(); 
    function2(); 
    return 0; 
} 

在電子xample,

  • 'function1()'有'程序範圍'。
  • 'function2()'有'文件範圍'。
  • 'Label1'有'功能範圍'。 (標籤名稱必須在功能範圍內是唯一的。「標籤」是具有函數作用域的唯一標識符。
  • 變量「I」具有「塊範圍」。
  • 變量「x」和「Y」具有「原型範圍」不能有兩個變量的名稱的‘x’或‘在函數參數列表Y’。

在上述例子中所述的可變i具有塊範圍。如果控制超出範圍(生活你不能訪問該變量

所以C提供了動態內存構造以符合acc在這些場景中記憶這些記憶。 例如:

int* function(void) 
{ 
    int *ptr = malloc(sizeof(int)); 
    *ptr = 5; 
    return ptr; 
} 

int main(void) 
{ 
    printf("%d", function()); 
    return 0; 
} 

printf的仍然將打印的值甚至可變ptr超出範圍,而是由ptr指向的存儲器仍然存在(有生命的)。

又讀https://stackoverflow.com/a/18479996/1814023