I recently ran into a frustrating memory leak "gotcha" involving Eigen. The following code compiles
template <typename Derived>
Eigen::PlainObjectBase<Derived> leaky(
const Eigen::PlainObjectBase<Derived> & A)
{
Derived B = A;
return B;
}
int main(int argc, char * argv[])
{
Eigen::MatrixXd A(10000,1);
Eigen::MatrixXd B = leaky(A);
}
but causes a memory leak (without any warnings/asserts from Eigen):
.main(33789,0x7fff7bb2d300) malloc: *** error for object 0x7f9ed188da00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
The problem seems to be the cast happening in the return. Changing the return type of leaky
to Derived
:
template <typename Derived>
Derived leaky(
const Eigen::PlainObjectBase<Derived> & A)
fixes the issue. Or it could be fixed by changing the type of B
inside leaky
to Eigen::PlainObjectBase<Derived>
.
Eigen::PlainObjectBase<Derived> B = A;
Update:
The preferred answer from the Eigen developers is that leaky()
should return Derived
. This is a little disappointing if I want to have A
and the return value be different types and I don't want to expose all possible types for the return (i.e. I only want to template on top of Eigen matrices).