指針沒有默認值。你的指針將指向它當前存儲的任何內容。由於您尚未初始化,因此行
newCell.subcells[i] = ...
有效地訪問內存的某些不確定部分。請記住,子單元[i]是相當於
*(newCell.subcells + i)
如果左側包含一些垃圾,你最終會加入到i
垃圾值,並在該位置不確定訪問內存。正如你說正確的,你必須初始化指針指向一些有效的內存區域:
newCell.subcells = malloc(bytecount)
該線後,您可以訪問,很多字節。關於其他內存來源,有不同類型的存儲都有其用途。你得到的是什麼類型取決於你擁有什麼樣的對象,以及你告訴編譯器使用哪個存儲類。
malloc
返回指向沒有類型的對象的指針。您可以將指針指向該內存區域,並且該對象的類型將有效成爲指向對象類型的類型。內存沒有初始化爲任何值,訪問速度通常較慢。如此獲得的物體被稱爲allocated objects
。
- 您可以在全局放置對象。他們的記憶將被初始化爲零。對於點,你會得到NULL指針,對於浮點數你也會得到一個合適的零。你可以依靠一個合適的初始值。
- 如果您有局部變量但使用
static
存儲類說明符,那麼您將具有與全局對象相同的初始值規則。內存通常以與全局對象相同的方式分配,但這絕不是必需的。
- 如果您有沒有任何存儲類說明符或
auto
的局部變量,那麼您的變量將被分配到堆棧上(即使C沒有這樣定義,這是編譯器實際上做的事情)。你可以使用它的地址,在這種情況下編譯器將不得不忽略優化,比如把它放到寄存器當然。
- 與存儲類說明符
register
一起使用的局部變量被標記爲具有特殊存儲。因此,你不能再使用它的地址了。在最近的編譯器中,由於其複雜的優化器,通常不需要使用register
。如果你真的很專業,那麼如果使用它,你可能會得到一些性能。
對象具有關聯的存儲持續時間,可用於顯示不同的初始化規則(正式地,它們只定義至少對象存在多久)。使用auto
和register
聲明的對象具有自動存儲持續時間,並且已初始化爲而不是。如果你想讓它們包含某些值,你必須明確地初始化它們。如果你不這樣做,它們將包含編譯器在開始生命週期之前留在堆棧上的任何東西。由malloc
(或該家族的另一個功能,如calloc
)分配的對象已分配了存儲時間。他們的存儲是而不是初始化。當使用calloc
時,例外情況是內存被初始化爲零(「真實」零,即所有字節爲0x00,不考慮任何空指針表示)。用static
和全局變量聲明的對象具有靜態存儲持續時間。他們的存儲是已初始化爲適合其各自類型的零。請注意,對象不得有類型,但獲取無類型對象的唯一方法是使用分配的存儲。 (C中的對象是「存儲區域」)。
那麼,什麼是什麼?這是固定的代碼。因爲一旦你分配了一塊內存,你就無法再回頭分配多少物品了,最好是總是把這個數存儲在某個地方。我已經將變量dim
引入了獲取計數值的結構。
Cell makeCell(int dim) {
/* automatic storage duration => need to init manually */
Cell newCell;
/* note that in case dim is zero, we can either get NULL or a
* unique non-null value back from malloc. This depends on the
* implementation. */
newCell.subcells = malloc(dim * sizeof(*newCell.subcells));
newCell.dim = dim;
/* the following can be used as a check for an out-of-memory
* situation:
* if(newCell.subcells == NULL && dim > 0) ... */
for(int i = 0; i < dim; i++) {
newCell.subcells[i] = makeCell(dim - 1);
}
return newCell;
}
現在,事情是這樣的昏暗= 2:
Cell {
subcells => {
Cell {
subcells => {
Cell { subcells => {}, dim = 0 }
},
dim = 1
},
Cell {
subcells => {
Cell { subcells => {}, dim = 0 }
},
dim = 1
}
},
dim = 2
}
注意,在C,不需要函數的返回值是一個對象。根本不需要存儲。因此,你不能改變它。例如,以下是不可能的:
makeCells(0).dim++
您將需要一個「自由功能」,再次釋放分配的內存。因爲分配的對象的存儲不會自動釋放。您必須撥打free
以釋放樹中每個subcells
指針的內存。這是留給你寫的練習:)
全局變量被初始化爲零。您省略了文件靜態和函數靜態變量;出於練習的目的,它們更像全局變量(初始化爲零),而不是自動變量。 – 2009-03-02 22:54:01