Hy all,
I believe that the following piece of code is generating memory leak?
/* External function to dynamically allocate a vector */ template <class T> T *dvector(int n){ T *v; v = (T *)malloc(n*sizeof(T)); return v; } /* Function that calls DVECTOR and, after computation, frees it */ void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){ int e,f,n,p; double *Left_Conserved; Left_Conserved = dvector<double>(NumberOfProperties); //do stuff with Left_Conserved // free(Left_Conserved); return; }
I thought that, by passing the pointer to DVECTOR, it would allocate it and return the correct address, so that free(Left_Conserved) would successfully deallocate. However, it does not seem to be the case.
NOTE: I have also tested with new/delete replacing malloc/free without success either.
I have a similar piece of code for allocating a 2-D array. I decided to manage vectors/arrays like that because I am using them a lot, and I also would like to understand a bit deeper memory management with C++.
So, I would pretty much like to keep an external function to allocate vectors and arrays for me. What’s the catch here to avoid the memory leak?
EDIT
I have been using the DVECTOR function to allocate user-defined types as well, so that is potentially a problem, I guess, since I don’t have constructors being called.
Even though in the piece of code before I free the Left_Conserved vector, I also would like to otherwise allocate a vector and left it ‘open’ to be assessed through its pointer by other functions. If using BOOST, it will automatically clean the allocation upon the end of the function, so, I won’t get a ‘public’ array with BOOST, right? I suppose that’s easily fixed with NEW, but what would be the better way for a matrix?
It has just occurred me that I pass the pointer as an argument to other functions. Now, BOOST seems not to be enjoying it that much and compilation exits with errors.
So, I stand still with the need for a pointer to a vector or a matrix, that accepts user-defined types, that will be passed as an argument to other functions. The vector (or matrix) would most likely be allocated in an external function, and freed in another suitable function. (I just wouldn’t like to be copying the loop and new stuff for allocating the matrix everywhere in the code!)
Here is what I’d like to do:
template <class T> T **dmatrix(int m, int n){ T **A; A = (T **)malloc(m*sizeof(T *)); A[0] = (T *)malloc(m*n*sizeof(T)); for(int i=1;i<m;i++){ A[i] = A[i-1]+n; } return A; } void Element::setElement(int Ptot, int Qtot){ double **MassMatrix; MassMatrix = dmatrix<myT>(Ptot,Qtot); FillInTheMatrix(MassMatrix); return; }
So, some important concepts discussed here helped me to solve the memory leaking out in my code. There were two main bugs:
The allocation with malloc of my user-defined types was buggy. However, when I changed it to new, leaking got even worse, and that’s because one my user-defined types had a constructor calling an external function with no parameters and no correct memory management. Since I called that function after the constructor, there was no bug in the processing itself, but only on memory allocation. So new and a correct constructor solved one of the main memory leaks.
The other leaking was related to a buggy memory-deallocation command, which I was able to isolate with Valgrind (and a bit a patience to get its output correctly). So, here’s the bug (and, please, don’t call me a moron!):
And that’s where an RAII, as I understood, would avoid misprogramming just like that. I haven’t actually changed it to a std::vector or a boost::scoped_array coding yet because it is still not clear to me if a can pass them as parameter to other functions. So, I still must be careful with delete[].
Anyway, memory leaking is gone (by now…) =D