2013-01-17 89 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说,可变长度数组从声明住直到其封闭范围的末尾:

对于这样一个对象,该对象不具有可变长度数组类型,其生命周期从 延伸到对象的声明,直到程序执行离开 声明的范围。