返回新分配的数组

时间:2015-12-14 18:47:13

标签: c++

在C ++中,当函数离开其范围时,局部变量会被破坏。

int* doubleValue(int x)
{
    int value = x * 2;
    return &value; // return nValue by address here
} // value destroyed here

但是我尝试了以下函数,似乎函数allocateArray的两个版本 运作良好

int* allocateArray(int size)
{
    return new int[size];
}

int* allocateArrayVar(int size)
{
    int* var = new int[size];
    return var;
}//I expected memory for var would be deallocated here

int _tmain(int argc, _TCHAR* argv[])
{
    {
    int* ar1 = allocateArray(10);
    ar1[0] = 1;// I can write into memory
    int* ar2 = allocateArrayVar(10);
    ar2[0] = 2;// I can write into memory
    }
}

allocateArrayallocateArrayVar之间有什么区别吗? 为什么allocateArrayVar确实有效但doubleValue()没有?

5 个答案:

答案 0 :(得分:4)

allocateArrayallocateArrayVar之间没有区别。 doubleValue返回一个指向局部变量的指针,该函数将在函数返回时被销毁(即,它超出范围),因此指针变为无效。但是,当您使用new运算符时,您正在堆上分配内存,这最终意味着内存保持有效,直到您在其上调用delete(为了避免内存,您应该这样做泄漏)。

答案 1 :(得分:4)

这两个功能没有区别。

但是,您的代码中的注释有点误导:

  

我预计var的内存将在此处取消分配

使用new的重点是,一旦超出范围,您的记忆就不会被释放。虽然var是"已取消分配",但并不是指向的数据(即*var)被解除分配。

程序员,在本例中,需要手动释放使用new分配的内存。这就是你如何做到的:

void dellocateArray(int* arr) {
  delete[] arr;
}

allocateArrayVar的作用原因,doubleValue并非来自管理记忆的人之间的区别:

  • 当使用new(或malloc等)分配某些内容时,它会在上创建,因此会被分配,直到程序员解除分配为止它与delete(或free等)。

  • 所有其他实例化都在堆栈上完成,一旦超出范围,将被解除分配。由于可以回收内存,因此无法保证该内存地址将包含您所期望的内容。

答案 2 :(得分:3)

您的困惑源于您对"本地变量的定义"。

编写以下代码时:

SIGTERM

是的,您正在返回本地变量int* allocateArrayVar(int size) { int* var = new int[size]; return var; } 的副本,但var的值是分配数组的内存地址。当内存分配有var时,它将存储在堆上,在您手动调用new之前,该堆不会被释放。

因此,当delete的调用者收到返回值时,即使allocateArrayVar本身不再存在,它仍会获得有效的内存地址。

将此方法与

进行对比
int* var

堆栈上分配int* doubleValue(int x) { int value = x * 2; return &value; // return nValue by address here } // value destroyed here 的位置。函数调用完成后,堆栈内存会被解除分配,因此这里的返回值无效(它指的是堆栈上的内存地址,而不是堆)。

答案 3 :(得分:3)

首先,在结果的情况下,allocateArrayallocateArrayVar之间没有区别。如果您想知道程序的工作方式是否存在差异,请尝试先编译版本,然后使用第二个函数编译而不进行优化,并使用生成汇编代码的选项。并比较它们;)

如果您使用的是new运算符,则操作系统会在所谓的堆上分配内存 - 这个位置不属于任何函数。 只有一种方法可以释放这种内存:使用delete运算符。

答案 4 :(得分:1)

关于返回引用,返回对局部变量的引用是一个坏主意(不起作用),因为当函数终止时局部变量超出范围。

在这种情况下,最好返回对象(包括指针),因为使用new分配的内存存储在堆存储中,只要使用delete运算符手动删除它就具有生存期。

参考:C ++ Primer。只爱这本书:)