返回VLA是否安全?

以下代码使用堆:

char* getResult(int length) { char* result = new char[length]; // Fill result... return result; } int main(void) { char* result = getResult(100); // Do something... delete result; } 

因此必须在某处删除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... } 

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

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

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

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

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

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

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

对于具有可变长度数组类型的对象 ,其生命周期从对象的声明扩展,直到程序的执行离开声明的范围.27)如果以递归方式输入范围,则对象的新实例是每次都创造。 对象的初始值是不确定的。

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

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

getResult()返回时,char数组result将超出范围并与函数调用的堆栈帧一起释放。 如果要保留函数结构,则必须调用malloc并稍后释放内存。