我听说你每次使用“new”时都应该“删除”,但是当我运行一个简单的测试程序(如下)时,我为arraySize或numLoops添加的数字似乎没什么区别。这会导致内存泄漏吗?
#include <iostream>
int main()
{
double *array;
const int arraySize = 100000;
const int numLoops = 100000;
for (int i = 0; i < numLoops; i++)
{
// do I need to call "delete [] array;" here?
array = new double[arraySize];
}
int x;
std::cin >> x; // pause the program to view memory consumption
delete [] array;
return 0;
}
答案 0 :(得分:9)
不,这还不够。
每次调用new
或new[]
时,都会分配一些内存,并为您提供该内存的地址(以便能够使用它)。每段内存最终必须为delete
d(或delete[]
d)。
您将该地址存储在array
中,但在下一次迭代时立即覆盖该地址。因此,您无法delete
- 已经分配了所有内存。因此,您有内存泄漏。
答案 1 :(得分:4)
有助于正确理解您实际上在做什么。
您没有在同一指针上调用new[]
两次。您正在调用new[]
两次,并将两个结果存储到同一指针中。 new[]
只返回指向已分配内存的指针。为避免泄漏内存,您必须在某个时刻再次释放内存。但是指针不是内存,它只是一个指针,告诉你分配的内存是的位置。
因此,您始终可以覆盖指针,将其设置为指向新的不同地址。然后你就失去了使用所指向的所有知识。如果它曾经指向你应该释放的内存,那么你就不能再找到那块内存了,所以你再也不能在它上面调用delete[]
了,所以......它被泄露了。
答案 2 :(得分:2)
是。你没有在指针上调用new
,你调用new
并返回指向已分配内存的指针。您有责任保留该指针并将其删除。如果你像现在一样覆盖那个值,那么你就是在泄漏。
答案 3 :(得分:1)
每当您new
(或new[]
)内存必须 delete
(或delete[]
)时,它或它都会泄漏。
每次调用new时,如果new
操作成功,则返回指向堆分配对象的指针。如果指向此内存的指针超出范围或被重新分配(即您在此处执行的操作),那么您将无法以后删除内存。
在您的代码示例中,仅销毁最后分配的内存。您可以使用process explorer甚至任务管理器之类的东西来检查内存泄漏。
答案 4 :(得分:1)
是。幸运的是,有一种更好的方法 - 使用std::vector
:
#include <iostream>
#include <vector>
int main()
{
double *array;
const int arraySize = 100000;
const int numLoops = 100000;
for (int i = 0; i < numLoops; i++)
{
std::vector<double> array(arraySize);
// use it just like a normal array
}
int x;
std::cin >> x; // pause the program to view memory consumption
return 0;
}
循环的每次迭代都会销毁vector
(以及它控制释放的内存)。
除非您确实需要,否则通常不应使用new
。我甚至可以说从来没有需要(甚至是很好的理由)使用new
的数组形式。
答案 5 :(得分:1)
两个问题,两个答案。
问题一:在同一指针上调用new []两次而不调用之间的delete []会导致内存泄漏吗?
答案一:并非总是如此,但99%的时间是肯定的。下面的代码使用指向数组的指针调用new两次,但第一次将分配的内存的地址分配给array2,第二次将地址保存到自身。在这种情况下,可以删除这两个数组。
#include <iostream>
int main()
{
double *array;
double *array2;
const int arraySize = 100000;
for (int i = 0; i < 2; i++)
{
// do I need to call "delete [] array;" here?
array = new double[arraySize];
if(i == 0)
{
array2 = array;
}
}
int x;
std::cin >> x; // pause the program to view memory consumption
delete [] array;
delete [] array2;
return 0;
}
问题二:delete []的这种用法是否足够?
答案二:不,因为删除调用只影响你给它的指针指向的地址。当您在示例中覆盖指针时,它会删除最后分配的内存部分