更改动态分配的数组的指针

时间:2017-03-19 08:19:34

标签: c++ pointers memory-leaks dynamic-allocation

当我们像这样动态声明某事时

int *ptr = new int [100];

然后更改指针地址(即将其指向其他地方)

int pointer[5] = {1,2,1,3,1,};
ptr = pointer ; 

现在包含100个整数的内存会发生什么?

无论如何重新控制那段记忆?如果没有,是否会导致内存泄漏?

3 个答案:

答案 0 :(得分:1)

  

现在包含100个整数的内存会发生什么?

它被“泄露”,因为你失去了你唯一的手柄。

  

无论如何重新控制那段记忆?

不,除非您在重新分配ptr之前注意创建另一个句柄。

int* ptr = new int[100];
int* ptr2 = ptr;
...
ptr = pointer;
delete [] ptr2;

在实际代码中,您不会依赖原始指针来分配内存,而是使用最适合您问题的RAII类型(例如std::vectorstd::unique_ptr等。)

答案 1 :(得分:1)

分配有new的任何内存块在释放之前都不可用,或者由相应的delete释放,或者在分配内存的进程终止时。

内存分配器实际上并不知道您在分配的对象上维护了哪些引用。如果您设法提供有效的地址,它只允许您释放相应的内存块。
如何跟踪这些地址完全取决于您。

因此,如果由于某种原因你忘记了一大块内存(通过覆盖你的例子中的数据指针,或者只是忘记在某些时候使用它来释放内存),你将剥夺系统的这一点在底层进程终止之前的内存。

如果“记忆失效”是无意的,那么这会成为内存泄漏,如果反复发生则更是如此。

例如,如果您需要一些与进程具有相同生命周期的数据,则可以进行一次性分配并永远不释放内存(因为它将在终止时自动释放)。这可能会使良好做法狂热者感到恐惧,但不会被视为记忆泄漏。

另一方面,还有其他方法搞乱内存分配器:将无效指针传递给delete(包括对已释放对象的引用,即多次删除对象的同一实例,或指向未由new分配的内容的指针,如本地或全局变量)将为您带来未定义行为的奇妙领域,这可能导致随机内存丢失,数据损坏或核崩溃。

答案 2 :(得分:1)

在您提供的示例中,ptr是引用由int创建的百new int [100]的唯一指针(即指向第一个元素的点)。

更改ptr的值不会影响百int。这意味着ptr不再包含第一个元素的地址。

实际上,在赋值ptr = pointer之后,分配的内存被认为是泄漏的 - 它已被分配,标准C ++中无法访问它,并且在标准C ++中无法释放它(例如使其消耗的内存可用于在另一个new表达式中重新分配。

在你的情况下保持对内存的控制的唯一方法是将ptr的值存储在另一个变量(或结构的成员,或指针数组的元素,.... )在重新分配之前。如果在重新分配ptr之前存储ptr的值,并且存储它的位置仍然存在,则可以检索该值。

实际上,最好使用标准容器(例如std::vector<int>)而不在代码中使用新表达式。这样,只要容器存在,容器的内容就是可访问的(并且就程序而言,当容器存在时,它就不再存在。)