There is a memory leak problem in my code, and I could not find where it is. The only place I use new/delete commands is for matrix. I am using the following way to create a matrix and free the memory when I am finished with it
-----------------------------------------
allocation:
double** Mat = new double* [row];
Mat[0] = new double [row * col];
for (int i = 1; i < row; ++i)
Mat[i] = Mat[i-1] + col;
deallocation:
delete [] Mat[0];
delete [] Mat;
-----------------------------------------
I think this way should free all the memory allocated by new and should not cause memory leak. Am I correct?
If I am right about this, then where else could memory leak happens? Memory issue is really a headache...
Thanks for the link. It is an interesting post, probably a more efficient way to implement multi-dim arrays, but does not solve my question.
I like the way to construct matrix in my first post. One nice feature of this way is that we do not need to pass other parameters at deallocation, except the double pointer. most other alternatives need a dimension parameter.
The thing I am not 100% sure whether the deallocation indeed frees all the memory is that, since we first delete[] Mat[0], the memory to store the actual data in the matrix is freed first. Thus after the first deletion, Mat[0], Mat[1],..., Mat[row-1] are probably null pointers (?), so when we delete[] Mat, do we free all the memory to hold these row pointers? I am thinking if these memory is not freed thoroughly, it may be the source of memory leak in my code.
When you have an array of pointers to heap memory, you first have to release the memory that each pointer points to, then you can delete the array of pointers.
And how do you know there is a memory leak?
In most cases of allocation of small objects, delete does not return the freed memory to the OS. It just marks the region to be reused when the next call to new happens. That is why many programs with manual allocation behave like they had leaks, despite the fact they don't have any. If you are very unlucky, your program can consume several times more memory from the OS than is really needed. Long running applications that do heavy caching of small objects often suffer from this: e.g. Firefox.
My code is doing simulation, and I observe that the memory usage goes up when I have more replications. and when I set replication to be very large, my code will crash with a message saying "This application has requested the Runtime to terminate it in an unusual way", and the memory usage is indeed at the limit of my computer. So I think there must be a memory leak in the code. If there is no memory leak, while the memory usage can go up, it should not crash, right?
One thing I did not mention is the way I use the matrix. I do not write a matrix class, instead, I first construct the matrix (double pointer) in the main function, then I pass the matrix (double pointer) to a sub-function to do some work, then at the end of the main function, I delete the matrix by the deallocation procedure.
I was thinking when I pass the matrix to the sub-function, I essentially create a copy of the matrix, so maybe I need to delete the copy inside the sub-function, but this is not right when I tried it out. so I guess it should not be a memory leak here.
The way you assign memory for the Mat arrays is kindof strange, maybe your problem is in there..
Also, In the article R0mai posted;
1 2 3 4 5 6 7 8 9 10 11 12
// let's say we want to dynamically make int[Y][X]:
int** superevil = newint*[Y];
for(int i = 0; i < Y; ++i)
superevil[i] = newint[X];
// now we can do this:
superevil[2][3] = 1;
// but cleanup is just as ugly as allocation:
for(int i = 0; i < Y; ++i)
delete[] superevil[i];
delete[] superevil;
You should probably just read the article and find a better solution instead of using int** Mat
The problem must be somewhere else. Try to use valgrind or electric fence - these tools will help you find the source of the leak.
@skillness: your way of allocation is slooooow - exactly how you should not do it - much worse than that of majia1. Each call to new is about 80-200 CPU cycles for the best allocators available. If you program this way, any beginner Java coder would rewrite your code literally in Java, and then create another "Java faster than C++" post on his blog.
If you would have read the article R0mai posted (instead of the article "Java faster than C++"), you woudlve known it is bad, and i think thats the reason the variable is called superevil
You should probably just read the article and find a better solution instead of using int** Mat
The article suggests using nested STL vectors which is just as slow - each vector needs to allocate and deallocate space. The approach of allocating one contiguous memory chunk and storing just pointers inside is much wiser, at least from the performance point of view. In languages with automatic allocation from contiguous memory chunk, you can new many times and it will be fast and will have good memory locality, but not in C++ - in C++ you need to plan your allocations very carefully.
I believe the second post provides better way to handle multi-dim arrays. However, I have finished all my code using the way in the first post, so it is not easy to change to an alternative way. While people may say that way is not as pretty, it works and has its own advantages.
One remaining memory problem is very weird, I provide an concrete example under topic with the name "memory leak detect using _CrtDumpMemoryLeaks" ( http://www.cplusplus.com/forum/general/26994/ ), but I think it is quick relevant and re-post here.
I made up a concrete example to show the problem. here is my code
as you can see, I comment out the delete command and the memory allocated by new is not freed, so memory leak is detected with the a nice report with location information:
Detected memory leaks!
Dumping objects ->
c:\...\visual studio 2008\projects\memorytest\memorytest\memorytest.cpp(41) : {122} normal block at 0x00336658, 12 bytes long.
Data: < > CD CD CD CD CD CD CD CD 01 00 00 00
c:\...\visual studio 2008\projects\memorytest\memorytest\memorytest.cpp(39) : {121} normal block at 0x00336618, 4 bytes long.
Data: <Xf3 > 58 66 33 00
Object dump complete.
Then I uncomment the delete statements, while I expect no memory leak, I get the report without location information:
for(int i = 0; i < Y; ++i)
superevil[i] = newint[X];
allocates 12 bytes, 4 for the int pointer (Y==1) and 8 for the two ints (X==2). And the error message for these 12 bytes disappears when you uncomment the delete statements. So, this is not the problem.
However, here:
superevil[0][2] = 1;
you have heap corruption. [0][2] is not a valid set of indices for your array. Maybe that's why you get that 4 byte error. Try commenting it out, or making it superevil[0][1] = 1; or superevil[0][0] = 1; and see what happens.
Then I un-comment the line to call the destructor v.~vector(), and the memory leaks disappears. However, I think we do not need to call the vector destructor explicitly, since it will be called automatically when the code exit. so I am confused why there is a memory leak in the code without explict call of the vector destructor.