更改动态分配数组的指针
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::vector
、std::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>
)而不是在代码中使用新表达式。这样,只要容器存在,就可以访问容器的内容(就您的程序而言,当容器存在时,容器的内容将不复存在)。
当我们像这样动态地声明一些东西时
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::vector
、std::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>
)而不是在代码中使用新表达式。这样,只要容器存在,就可以访问容器的内容(就您的程序而言,当容器存在时,容器的内容将不复存在)。