2013-01-17 122 views
1

這是否總是按預期運行?可變尺寸陣列的範圍

char *x; 
if (...) { 
    int len = dynamic_function(); 
    char x2[len]; 

    sprintf(x2, "hello %s", ...); 

    x = x2; 
} 

printf("%s\n", x); 
// prints hello 


編譯器如何(在我的情況GCC)實現可變大小的數組,每個C和C++的?

+0

取決於語言。這是C++中的一個編譯器擴展。 – chris

+0

它沒有。由於您聲明瞭一個變量char x2 [],因此它會從堆/進程虛擬內存中詢問空間並始終保持相同。 當你寫x = x2時,你將x指向與x2相同的內存空間,因爲x是一個指針,但它不會總是一樣,printf x沒有初始化就會打印垃圾。 –

+3

根據我的理解,x2在if語句後不復存在,因此無法知道打印輸出是什麼 – Smash

回答

5

編號x2位於if語句的作用域的本地,您可以使用指針在其外部訪問它。這導致未定義的行爲。

順便說一下,在C11中,VLA已經成爲可選項,並且從未成爲C++的一部分。所以最好避免它。

+0

另一方面,VLA的(非常)受限形式正在悄悄進入下一個C++標準;-) –

+0

VLA僅在C99中添加,甚至在C99變得普遍之前,它有點尷尬,他們刪除了它從標準! –

2

範圍解釋here

跳躍或爆發陣列名稱的範圍的重新分配該 存儲。跳入範圍是不允許的;您收到錯誤消息 。

在你的情況下,數組超出範圍。

2

否,對於兩個單獨的原因:

C++:該代碼是無效的C++。 C++中的數組必須具有編譯時常量大小。

C:不,因爲該數組只能存在,直到它聲明的塊的末尾,因此解引用x是未定義的行爲。

從C11,6.2.4/2:

如果對象被稱爲它的壽命之外,則該行爲是未定義的。

而且6.2.4/7說,可變長度數組從聲明住直到其封閉範圍的末尾:

對於這樣一個對象,該對象不具有可變長度數組類型,其生命週期從 延伸到對象的聲明,直到程序執行離開 聲明的範圍。