C++ 可变大小数组的作用域

C++ 可变大小数组的作用域,c++,c,gcc,C++,C,Gcc,这是否总是按照预期运行 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++中的每一个?< p>范围被解释: 跳出或突破数组名称的范围将取消分配 存储不允许跳入该范围;你

这是否总是按照预期运行

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++中的每一个?

< p>范围被解释:

跳出或突破数组名称的范围将取消分配 存储不允许跳入该范围;你犯了一个错误 给它留言

在您的情况下,阵列超出范围。

范围如下:

跳出或突破数组名称的范围将取消分配 存储不允许跳入该范围;你犯了一个错误 给它留言

在您的情况下,数组超出范围。

否。x2是if语句范围的局部,您可以使用指针在其范围之外访问它。这会导致未定义的行为

顺便说一下,VLAs在C11中被选择了,并且从来没有成为C++的一部分。所以最好避免它。

否。x2是if语句作用域的局部,您可以使用指针在其外部访问它。这会导致未定义的行为


顺便说一下,VLAs在C11中被选择了,并且从来没有成为C++的一部分。所以最好避免它。

不,原因有两个:

C++:代码不是有效的C++。C++中的数组必须具有编译时常数大小。 C:不,因为数组只存在到声明它的块的末尾,因此取消引用x是未定义的行为

从C11,6.2.4/2:

如果对象在其生存期之外被引用,则该行为未定义

并且6.2.4/7说可变长度数组从其声明一直存在到其封闭范围结束:

对于具有可变长度数组类型的对象,其生存期从 对象的声明,直到程序的执行离开 声明


不,原因有两个:

C++:代码不是有效的C++。C++中的数组必须具有编译时常数大小。 C:不,因为数组只存在到声明它的块的末尾,因此取消引用x是未定义的行为

从C11,6.2.4/2:

如果对象在其生存期之外被引用,则该行为未定义

并且6.2.4/7说可变长度数组从其声明一直存在到其封闭范围结束:

对于具有可变长度数组类型的对象,其生存期从 对象的声明,直到程序的执行离开 声明


取决于语言。它是C++中的编译器扩展。由于您声明了一个变量char x2[],它的空间是从堆/进程虚拟内存中请求的,并且始终保持不变。当您写入x=x2时,您使x指向与x2相同的内存空间,因为x是指针。但它并不总是一样的,没有初始化的printf x将打印垃圾。据我所知,在if语句之后,x2不再存在,因此无法知道打印输出将是什么,这取决于您是否期望它正常工作。如果您这样做了,那么不会,它不会像预期的那样工作。也许您将VLAs与非标准函数alloca混淆了-alloca分配的内存确实有效,直到封闭函数作用域结束,并且独立于本地作用域。这取决于语言。它是C++中的编译器扩展。由于您声明了一个变量char x2[],它的空间是从堆/进程虚拟内存中请求的,并且始终保持不变。当您写入x=x2时,您使x指向与x2相同的内存空间,因为x是指针。但它并不总是一样的,没有初始化的printf x将打印垃圾。据我所知,在if语句之后,x2不再存在,因此无法知道打印输出将是什么,这取决于您是否期望它正常工作。如果你这样做了,那么不会,它不会像预期的那样工作。也许你把VLA和非标准函数alloca混淆了-alloca分配的内存在封闭函数作用域结束之前确实有效,并且独立于局部作用域。另一方面,VLA的一种非常受限的形式是潜入下一个C++标准;这有点尴尬,因为VLA仅在C99中添加,甚至在C99普及之前,他们就将其从标准中删除了!另一方面,VLA的一种非常受限的形式是潜入下一个C++标准;这有点尴尬,因为VLA仅在C99中添加,甚至在C99普及之前,他们就将其从标准中删除了!