2012-08-01 150 views
0

想,我寫了一個函數如下:內存分配

void foo() 
{ 
    char *strArr[] = {"AA", "BB", "CC"}; 
    ... 
} 

凡strArr將分配?什麼時候會被初始化?

出於某種原因,我記得,這樣的陣列將靜態存儲空間分配,而不是在棧和初始化在程序啓動,就好像我以前會寫「靜態」。這是假記憶嗎?

回答

3

該數組將被分配爲本地對象。在一般情況下,當函數開始執行時,所有本地對象的內存可以提前分配,或者可以「按需」分配,因爲控制使用對象聲明輸入嵌套塊。該語言沒有指定確切的時刻。

在您的具體例子爲陣列的存儲器將在功能開始執行,因爲你的陣列在功能的「主」塊中聲明進行分配。

至於初始化...在C89/90的版本的C所有集合初始化必須是常數表達式,這意味着該集合初始化過程可以不依賴於任何運行時的值。初始化可以被硬編碼到編譯的程序中,並且可以在分配數組之後立即發生。

在C99可以在聚合初始化使用運行時的值,這意味着,當控制經過申報實際intialization可能會推遲到如此地步。

在您的例子的陣列被初始化爲常量表達式,這意味着它可以立即分配之後initailized。編譯器實際上可以事先準備一個數組的靜態副本,並且每次控制進入函數時都可以將其「粘貼」到堆棧中。

P.S.您對「靜態內存」的引用實際上適用於用於初始化數組元素的字符串文字(如"AA")。字符串文字確實駐留在靜態內存中。但是,字符串文字是完全獨立的對象,而您的strArr數組是一個完全獨立的對象。

注意,你真的沒有在你的例子是「字符串數組」。你有什麼是指針到字符串的數組。您的strArr居住在本地內存中,而字符串(strArr點的元素)存在於靜態內存中。

5

它具有自動存儲功能,因此它將被分配在函數的堆棧中。這些元素屬於這種自動存儲,但字符串文字本身存儲在一個持久的,可能只讀的區域。

+0

元素指向字符串文字的第一個元素,而不是字符串文字本身。 – 2012-08-01 06:57:51

+0

@R ..當然,這是正確的。 – cnicutar 2012-08-01 06:58:56

1

我剛剛拆解了一個示例程序。

#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只會被分配到棧中。因爲它是自然的。