Reputation: 1971
I want to know whether I need to free up the memory occupied by locations
and values
objects after sparse matrix has been created. Here is the code:
void load_data(umat &locations, vec& values){
// fill up locations and values
}
int main(int argc, char**argv){
umat loc;
vec val;
load_data(loc,val);
sp_mat X(loc,val);
return 0;
}
In the above code, load_data()
fills up the locations
and values
objects and then sparse matrix is created in main()
. My Q: Do I need to free up memory used by locations and values after construction of X
? The reason is that X
could be large and I am on low RAM. I know when main returns, OS will free up locations
and values
as well as X
. But, the real question is whether the memory occupied by X
is the same as by locations
and values
OR X
is allocated memory separately and I need to free locations
and values
in the case.
Upvotes: 0
Views: 650
Reputation: 911
The constructor (SpMat_meat.hpp:231) you are using
template<typename T1, typename T2>
inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, const bool sort_locations = true);
fills the sparse matrix with copies of the values in values
.
I understand you are worried that you will run out of memory and if you keep loc
, val
and X
separately you basically have two copies of the same data, taking up twice as much memory as actually needed (this is indeed what happens in your code snippet), so I will try to focus on addressing this problem and give you a few options:
1) If you are fine with keeping two copies of the data for a short while, the easiest solution is to dynamically allocate loc
and val
and delete them right after initialization of X
int main(int argc, char**argv){
umat* ploc;
vec* pval;
load_data(*ploc,*pval);
// at this point we have one copy of the data
sp_mat X(*ploc,*pval);
// at this point we have two copies of the data
delete ploc;
delete pval;
// at this point we have one copy of the data
return 0;
}
Of course you can use safe pointers instead of C style ones, but you get the idea.
2) If you absolutely don't want to have two copies of the data at any time, I would suggest that you modify your load_data
routine to sequentially load values one by one and directly insert them into X
void load_data(umat &locations, vec& values, sp_mat& X){
// fill up locations and values one by one into X
}
Other options would be to i) use move semantics to directly move the values in val
into X
or ii) directly use the memory allocated for val
as the memory for X
, similar to the advanced constructor for matrices
Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = false)
Both options would however require modifications on the level of the armadillo library, as such a functionality is not supplied yet for sparse matrices (There is only a plain move constructor so far). It would be a good idea to request these features from the developers though!
Upvotes: 1