返回VLA是否安全?

Luk*_*uke 2 c c++ gcc dynamic-arrays

以下代码使用堆:

char* getResult(int length) {
    char* result = new char[length];
    // Fill result...
    return result;
}

int main(void) {
    char* result = getResult(100);
    // Do something...
    delete result;
}
Run Code Online (Sandbox Code Playgroud)

因此result必须在某处删除,最好由所有者删除.

根据我的理解,下面的代码使用名为VLA的扩展,它是C99的一部分,而不是C++标准的一部分(但是由GCC和其他编译器支持):

char* getResult(int length) {
    char result[length];
    // Fill result...
    return result;
}

int main(void) {
    char* result = getResult(100);
    // Do something...
}
Run Code Online (Sandbox Code Playgroud)

假设result在这种情况下仍然在堆栈上分配,我是否正确?

result副本,还是垃圾内存的引用?以上代码是否安全?

Sha*_*our 5

您不能返回它,在C 中它将具有自动存储持续时间(一旦离开范围,对象将无效)并且返回它将调用未定义的行为,来自C99 草案标准部分6.2.4 对象的存储持续时间6段:

对于这样一个具有可变长度数组类型的对象,它的生命周期从对象的声明开始,直到程序的执行离开声明的范围。27) 如果范围是递归进入的,则对象的新实例是每次创建。对象的初始值是不确定的。

C++ 中,我们必须依赖文档,因为在这种情况下它是扩展,并且VLA 上gcc 文档说它在范围结束时被释放:

这些数组的声明方式与任何其他自动数组类似,但其长度不是常量表达式。存储在声明点分配,并在包含声明的块作用域退出时解除分配。


oua*_*uah 5

假设在这种情况下仍然在堆栈上分配结果,我是否正确?

正确.VLA具有自动存储持续时间.

结果是副本,还是垃圾内存的引用?以上代码是否安全?

代码不安全.返回的地址getResult是无效的地址.取消引用指针会调用未定义的行为.