2010-08-19 34 views
2

gcc 4.4.3 c89初始化分配一個數組的大小

我想知道爲什麼我不能在初始化指向char的指針數組時分配數組的大小。

我得到以下錯誤:

variable-sized object may not be initialized 

該工程確定。但是,sizeof將返回4個字節,因爲char *的大小爲4個字節。這是不好的,因爲它不是我想要的實際大小。

void inc_array(const char * const src, size_t size) 
{ 
    /* Array of pointers */ 
    char *dest[sizeof(src)] = {0}; 
} 

但是,這是我想要做的就是傳遞實際大小並使用它來初始化數組的長度。

void inc_array(const char * const src, size_t size) 
{ 
    /* Array of pointers */ 
    char *dest[size] = {0}; 
} 

當sizeof返回一個size_t並且我傳遞一個size_t時,有什麼區別?

非常感謝您的任何建議,

回答

2

隨着錯誤消息指出,可變長度數組無法初始化 - 也就是說,= { 0 }部分就是問題所在。你仍然可以使用可變長度的數組 - 你只需要明確地初始化它:

void inc_array(const char * const src, size_t size) 
{ 
    /* Array of pointers */ 
    size_t i; 
    char *dest[size]; 

    for (i = 0; i < size; i++) 
     dest[i] = 0; 
} 
+0

是的,你是對的。我剛剛測試過。 – ant2009 2010-08-19 05:14:42

+0

所以VLA完全可以接受它,只有當你嘗試並初始化它們。我已經標明這是正確的,因爲這是我得到這個錯誤的真正原因。謝謝。 – ant2009 2010-08-19 06:41:13

+0

@robUK:它們在當前的C標準中是可以接受的,並且作爲舊C標準的gcc擴展。 – caf 2010-08-19 07:07:49

4

使用malloc分配動態大小的數組。

您還必須確保malloc版數據是最終free d。

+0

感謝您的教程。我知道malloc和free。但是,我只是想知道爲什麼我可以下面的char * dest [sizeof(src)],我不能做char * dest [size]?謝謝 – ant2009 2010-08-19 03:03:33

+0

@robUK - 請參閱編輯我的回答 – 2010-08-19 03:04:34

+1

@rob:我明白了。恰好是'sizeof(src)'在編譯時已知的情況,但'size'不是。這是問題的根源。 – kbrimington 2010-08-19 03:05:30

4

在C89你根本無法做到這一點 - 可變大小的數組C99之前不支持。數組大小需要是編譯時常量。你想要的東西:

void inc_array(const char * const src, size_t size) { 
    char ** dest = calloc(size, sizeof(char*)); 
    /* do stuff with dest here! */ 
} 

我不確定你想要一個指針數組雖然。我本來期望如下:

void inc_array(const char * const src, size_t size) { 
    char *dest = calloc(size, sizeof(char)); 
    memcpy(&dest[0], &src[0], size); 
    /* do stuff with dest */ 
    free(dest); 
} 

編輯:我忘了回答你的問題的第二部分。

的區別在於sizeof(src)是編譯時表達式(這個),因爲它是計算類型的大小。在這種情況下,它是相同的sizeof(char*)這是你的平臺上可能是32位。然而,在sizechar *dest[size]不能靜態地確定。兩者都是size_t值,但C89要求在靜態分配的陣列元素的數量是在編譯時確定。這就是爲什麼你不得不求助於動態分配。

+1

錯誤不是變長數組不支持*,而是它們不能被*初始化*。很顯然,OP的編譯器支持C99。 – caf 2010-08-19 04:31:37

+0

我認爲gcc支持作爲GNU擴展的VLA版本。我應該簡單地說在C89中不支持VLA。我將在更改中進行編輯。 – 2010-08-19 14:52:17

1

sizeof操作符不工作,你會想到的原因是一個數組「衰變」一個指針,當你把它傳遞給一個函數:

int array[5]; 
printf("%d\n", sizeof(array)/sizeof(int)); /* prints 5 */ 

/* ... */ 

void some_function(int array[]) 
{ 
    printf("%d\n", sizeof(array)/sizeof(int)); /* prints 1, no matter what */ 
} 

至於定義你的陣列,在舊版本的C,可變長度數組是不允許的(請注意,Visual Studio仍然實現這個舊版本的C)。你必須指定一個固定的大小:

const size_t some_size = 22; 
size_t some_other_size = 5; 
int array1[5]; /* okay */ 
int array2[some_size]; /* okay */ 
int array3[some_other_size]; /* not okay - not const */ 

C(實現C99標準的編譯器)的新版本允許你指定一個可變大小:

size_t some_other_size = 5; 
int array3[some_other_size]; /* okay - VLA */ 

作爲一個側面說明,沒有版本的C++標準已包含對VLA的支持。一些C++編譯器已經實現了自己的擴展,但是(請參閱Groxx的評論)。

如果你想分配在C編譯器的連續內存變量量不支持沃拉斯,你必須使用malloc和free,爲kbrimington建議:

size_t size = 5; 
int* array = (int*)malloc(sizeof(int) * size); 
/* use array */ 
free(array); 
+0

「C++的任何版本都沒有允許VLA」 - - 完全不準確。 C99,你提到的那個,確實如此。 http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html或http://en.wikipedia.org/wiki/Variable-length_array#Examples(注意第一個例子)。當我使用GCC進行編譯時,導致了一些問題,並且我的教授正在使用Visual Studio使用的任何編譯工具。 – Groxx 2010-08-19 03:26:55

+0

@Groxx:我想我應該改爲「沒有任何版本的C++標準包含了對VLA的定義」。它是GCC和IBM的C++編譯器的擴展。我正在談論C++,而不是C,儘管我知道問題是關於C的。這只是一個附註:) – 2010-08-19 03:35:12