想,我寫了一個函數如下:內存分配
void foo()
{
char *strArr[] = {"AA", "BB", "CC"};
...
}
凡strArr將分配?什麼時候會被初始化?
出於某種原因,我記得,這樣的陣列將靜態存儲空間分配,而不是在棧和初始化在程序啓動,就好像我以前會寫「靜態」。這是假記憶嗎?
想,我寫了一個函數如下:內存分配
void foo()
{
char *strArr[] = {"AA", "BB", "CC"};
...
}
凡strArr將分配?什麼時候會被初始化?
出於某種原因,我記得,這樣的陣列將靜態存儲空間分配,而不是在棧和初始化在程序啓動,就好像我以前會寫「靜態」。這是假記憶嗎?
該數組將被分配爲本地對象。在一般情況下,當函數開始執行時,所有本地對象的內存可以提前分配,或者可以「按需」分配,因爲控制使用對象聲明輸入嵌套塊。該語言沒有指定確切的時刻。
在您的具體例子爲陣列的存儲器將在功能開始執行,因爲你的陣列在功能的「主」塊中聲明進行分配。
至於初始化...在C89/90的版本的C所有集合初始化必須是常數表達式,這意味着該集合初始化過程可以不依賴於任何運行時的值。初始化可以被硬編碼到編譯的程序中,並且可以在分配數組之後立即發生。
在C99可以在聚合初始化使用運行時的值,這意味着,當控制經過申報實際intialization可能會推遲到如此地步。
在您的例子的陣列被初始化爲常量表達式,這意味着它可以立即分配之後initailized。編譯器實際上可以事先準備一個數組的靜態副本,並且每次控制進入函數時都可以將其「粘貼」到堆棧中。
P.S.您對「靜態內存」的引用實際上適用於用於初始化數組元素的字符串文字(如"AA"
)。字符串文字確實駐留在靜態內存中。但是,字符串文字是完全獨立的對象,而您的strArr
數組是一個完全獨立的對象。
注意,你真的沒有在你的例子是「字符串數組」。你有什麼是指針到字符串的數組。您的strArr
居住在本地內存中,而字符串(strArr
點的元素)存在於靜態內存中。
它具有自動存儲功能,因此它將被分配在函數的堆棧中。這些元素屬於這種自動存儲,但字符串文字本身存儲在一個持久的,可能只讀的區域。
我剛剛拆解了一個示例程序。
#include <stdio.h>
void foo()
{
char *strArr[] = {"AA", "BB", "CC"};
}
int main()
{
foo();
return 0;
}
看來,字符串文字將被分配在.rodata
部分。
.file "sfsfs.c"
.section .rodata
.LC0:
.string "AA"
.LC1:
.string "BB"
.LC2:
.string "CC"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
.....
.....
但是strArr只會被分配到棧中。因爲它是自然的。
元素指向字符串文字的第一個元素,而不是字符串文字本身。 – 2012-08-01 06:57:51
@R ..當然,這是正確的。 – cnicutar 2012-08-01 06:58:56