返回VLA是否安全?

时间:2013-09-12 17:54:43

标签: 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;
}

所以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是副本,还是垃圾内存的引用?以上代码是否安全?

3 个答案:

答案 0 :(得分:5)

  

我认为在这种情况下仍然在堆栈上分配结果是正确的吗?

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

  

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

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

答案 1 :(得分:4)

您无法退回,在 C 中它将具有自动存储持续时间(一旦您离开范围,该对象将无效)并且返回它将调用{ {3}},来自undefined behavior部分6.2.4 对象的存储持续时间段落 6

  

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

C ++ 中,我们必须依赖文档,因为在这种情况下它是扩展名,C99 draft standard表示在作用域结束时它被释放:

  

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

答案 2 :(得分:0)

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