更改动态分配数组的指针

changing pointer of a dynamically allocated array

当我们像这样动态地声明一些东西时

int *ptr = new int [100];

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

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

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

有没有办法重新控制那段记忆?如果不是,是否会导致内存泄漏?

now what happens to that memory which contained 100 integers?

它是 "leaked" 因为您丢失了唯一的句柄。

is there anyway to regain control of that memory ?

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

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

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

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

内存分配器实际上并不知道你在已分配上维护什么引用 objects.It 只允许你在设法提供有效地址时释放相应的内存块。
如何跟踪这些地址完全取决于您。

因此,如果由于某种原因你失去了对一块内存的跟踪(通过在你的示例中覆盖数据指针,或者只是忘记在某个时候使用它来释放内存),你将剥夺你的系统这段内存直到底层进程终止。

如果 "memory lapse" 是无意的,这将成为内存泄漏,如果这种情况反复发生,则更是如此。

比如你需要一些和进程有相同生命周期的数据,你可以做一次性分配,永不释放内存(因为它会在终止时自动释放)。这可能会吓坏良好做法的狂热者,但仍然不能算作内存泄漏。

另一方面,还有其他方法可以扰乱内存分配器:将无效指针传递给 delete(包括对已释放对象的引用,即删除对象的同一实例不止一次,或者指向未由 new 分配的东西的指针,如局部或全局变量)将带给您未定义行为的美妙境界,这可能导致随机内存丢失、数据损坏或核崩溃。

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

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

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

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

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