例如,当我按照以下方式分配内存时,我可以看到这种情况:
Position* arr1 = new Position[5];
位置是我程序中的一个类,用于描述具有x和y值的位置点。
堆栈上会有一个指针指向堆上数组“arr1”的第一个元素(一个Position对象),所以它看起来像这样:
如果我要创建一个指针数组,它会怎样?例如:
Position** arr2 = new Position* [2];
arr[0] = new Position(3, 7); // Constructs a point with x and y values.
arr[1] = new Position(9,6);
在我的第二个例子中,存储在内存中的所有指针和对象在哪里?堆栈上是否有指针指向堆上的指针,指针指向堆上的对象或什么东西?
另外,如果我去delete [] arr2;
,那么对象会留在内存中吗?
感谢。
答案 0 :(得分:3)
new
创建的每个对象都在堆上。所以在你的例子中,两个指针的数组将在堆上。作为局部变量的arr2
将在堆栈中。Position
单独分配的new
个对象位于各自的堆块中。他们需要单独delete
d。否则,他们仍然在堆上。对象无法在堆栈和堆之间移动。 (虽然C ++ 11提供了std::move
,但这实际上是一种特殊的所有权转移;它并没有神奇地将堆地址转换为堆栈地址。)delete [] arr2
会将对象留在内存中。由于指针数组不拥有引用的对象,因此该代码不会要求销毁间接引用的对象。您应该始终避免直接使用new
和delete
来支持容器对象(std::vector
或std::array
可以在这里工作),或智能指针,例如{{1 }和unique_ptr
。
答案 1 :(得分:2)
您有一个自动变量arr2
指针对象。其余的都在免费商店。如果只有delete[] arr2
,你将释放指针的内存,而不是它们指向的对象。
arr2 ---+ +---------------------------------+
| | |
| | |
+----> [Position*, Position*] |
| | | |
| | +----> [9, 6] |
| v |
| [3, 7] |
+---------------------------------+
答案 2 :(得分:1)
数组arr2的指针将在堆栈上。其他指针arr2 [0],arr2 [1]等将在堆上,这些指针将指向堆上的不同位置。
答案 3 :(得分:0)
您的图表将具有额外的间接级别。因此,将myArray
替换为arr2
,arr2[0]
和arr2[1]
。然后,仍然在堆上,绘制另一个箭头从arr2[0]
到Position value
,从arr2[1]
到另一个Position
值。
如果您使用delete[] arr2
,这些值将保留在最初分配的内存中的任何位置。