可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've heard that you should usually "delete" whenever you use "new", yet when I run a simple test program (below), it doesn't seem to make a difference which numbers I put for arraySize or numLoops. Does this cause a memory leak?
#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;
}
回答1:
No, it's not sufficient.
Each time you call new
or new[]
, some memory is allocated, and you are given the address of that memory (in order to be able to use it). Each piece of memory must eventually be delete
d (or delete[]
d).
You are storing that address in array
, but then immediately overwriting it on the next iteration. Therefore you have no way of delete
-ing all of pieces of memory that you've been allocated. Therefore you have a memory leak.
回答2:
It helps to understand correctly what you are actually doing.
You are not calling new[]
twice on the same pointer. You are calling new[]
twice, and storing both results into the same pointer. new[]
simply returns a pointer to the allocated memory. To avoid leaking memory, you have to free that memory again at some point. But the pointer is not the memory, it is just a pointer telling you where the allocated memory is.
So you can always overwrite the pointer, setting it to point to a new, different address. And then you just lost all knowledge of where it used to point to. If it used to point to memory that you ought to free, then you can no longer find that chunk of memory, so you can no longer call delete[]
on it, and so... it is leaked.
回答3:
Yes. You don't call new
on a pointer, you call new
and it returns a pointer to the allocated memory. You are responsible for holding onto that pointer and deleting it. If you overwrite that value, as you are, you are leaking.
回答4:
Yes. Fortunately, there's a better way -- instead of allocating the memory directly, use 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;
}
The vector
will be destroyed (and the memory it controls released) each iteration of the loop.
You shouldn't generally use new
unless you really need to. I'd go so far as to say there's never a need (or even good reason) to use the array form of new
.
回答5:
Two questions, two answers.
Question one: Does calling new [] twice on the same pointer without calling delete [] in between cause a memory leak?
Answer one: Not always, but 99% of the time yes. The code below calls new twice, with the pointer to array, but the first time it assigns the address of the allocated memory to array2, and the second time it keeps the address to itself. It is possible to delete both array in this scenario.
#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;
}
Question Two: Is this usage of delete [] sufficient?
Answer Two: no, because the delete call only influences the address pointed to by the pointer you've given it. As you overwrote the pointer in your example, it deletes the last allocated section of memory
回答6:
Whenever you new
(or new[]
) memory you must delete
(or delete[]
) it or it will leak.
Each time you call new you get returned a pointer to the heap allocated object if the new
operation succeeds. If the pointer to this memory goes out of scope or is reassigned (i.e. what you are doing here) then you will be unable to delete the memory later.
In your code example, only the last allocated memory will be destroyed. You can use something like process explorer or even task manager to check for memory leaks.