返回新分配的数组
Return newly allocated array
在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
}
}
allocateArray
和allocateArrayVar
之间有什么区别吗?为什么allocateArrayVar
有效而doubleValue()
无效?
这两个函数之间没有区别。
然而,代码中的注释有点误导:
我原以为
var
的内存会在这里被释放
使用new
的目的是,一旦内存超出范围,就不会释放内存。虽然var
是"解除分配"的,但指向的数据(即*var
)并不是解除分配的。
在这种情况下,程序员需要手动解除分配使用new
分配的内存。这就是你可以做到的:
void dellocateArray(int* arr) {
delete[] arr;
}
allocateArrayVar
工作但doubleValue
不工作的原因来自于谁管理内存之间的区别:
当用
new
(或malloc
等)分配某个东西时,它会在堆上创建,并因此进行分配,直到程序员用delete
(或free
等)解除分配。所有其他实例化都是在堆栈上完成的,一旦超出范围,就会被释放。因为内存可以回收,所以不能保证该内存地址会包含您所期望的内容。
allocateArray
和allocateArrayVar
之间没有差异。doubleValue
返回一个指向局部变量的指针,当函数返回(即超出范围)时,该变量将被销毁,因此指针变为无效。然而,当您使用new
运算符时,您正在堆上分配内存,这最终意味着内存在您对其调用delete
之前保持有效(您确实应该这样做以避免内存泄漏)。
您的困惑源于您对"局部变量"的定义。
当您编写以下代码时:
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
其中int value
分配在堆栈上。函数调用完成后,堆栈内存确实会被释放,因此这里的返回值是无效的(它指的是堆栈上的内存地址,而不是堆)。
首先,在结果的情况下,allocateArray
和allocateArrayVar
之间没有差异。如果您想知道程序的工作方式是否存在差异,请尝试在不进行优化的情况下,使用生成汇编代码的选项,先使用第一个函数,然后使用第二个函数编译版本。并进行比较;)
如果使用new
运算符,操作系统将在所谓的堆上分配内存,该堆不属于任何函数。只有一种方法可以解除分配此类内存:使用delete
运算符。
关于返回引用,返回对局部变量的引用是个坏主意(行不通),因为当函数终止时,局部变量会超出范围。
在这种情况下,最好返回对象(包括指针),因为使用new
分配的内存存储在堆存储中,只要使用delete
运算符手动删除,堆存储就有其生存期。
参考:C++初级读本。很喜欢那本书:)
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 具有自定义构造函数 (C++) 的类型的动态数组分配
- 如何通过 malloc 为队列数组分配内存?
- 具有动态数组分配的OpenMP嵌套循环
- 如何为数组结构的数组分配内存
- 如何为结构数组分配内存?
- cpp 数组 - 分配常量索引有效,而非常量索引不起作用
- 如何为字符指针数组分配内存?
- 在 C++ 中初始化后的数组分配
- 将数据分配给了数组分配,但程序显示了以缓冲区超支的输出
- C++函数问题中的数组分配
- 子数组分配:使用聚合对象错误的预期"{...}"进行初始化
- 为什么我的指针数组分配不起作用
- std::堆栈和堆栈溢出错误的数组分配
- 在 c++ 中是否有通过声明"implicit"数组分配?
- 在 c++ 中为 2-D "Dynamically Created"数组分配值时遇到问题
- 如何为C++数组分配指向第一个元素的指针
- 字符数组分配
- 将数组分配在固定数量的线程之间
- 为构造函数中的数组分配值