当我们像这样动态声明某事时
int *ptr = new int [100];
然后更改指针地址(即将其指向其他地方)
int pointer[5] = {1,2,1,3,1,};
ptr = pointer ;
现在包含100个整数的内存会发生什么?
无论如何重新控制那段记忆?如果没有,是否会导致内存泄漏?
答案 0 :(得分:1)
现在包含100个整数的内存会发生什么?
它被“泄露”,因为你失去了你唯一的手柄。
无论如何重新控制那段记忆?
不,除非您在重新分配ptr
之前注意创建另一个句柄。
int* ptr = new int[100];
int* ptr2 = ptr;
...
ptr = pointer;
delete [] ptr2;
在实际代码中,您不会依赖原始指针来分配内存,而是使用最适合您问题的RAII类型(例如std::vector
,std::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>
)而不在代码中使用新表达式。这样,只要容器存在,容器的内容就是可访问的(并且就程序而言,当容器存在时,它就不再存在。)