Re: [eigen] Assignment to MatrixBase fails assertion or SEGVs

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


2009/10/30 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
> ah wait, i hit "send" too fast.
>
> There's actually a very, very good reason why your code can't work.
>
> When you do
>  MatrixBase<Matrix2f> noinit;
>
> you're constructing an object of MatrixBase which is an empty class.
> The static array float[4] never gets reserved by the compiler. Hence
> that object noinit is definitively unusable; even casting it as a
> Matrix2f will just result in segfaults since one'll be addressing 4
> bytes at a location where typically 1 byte (size of an empty class)
> was reserved.
>

the following was also written too fast:

> The dynamic-size variant is broken too: the array that would normally
> be allocated in the Matrix constructor, never gets allocated because
> the Matrix constructor never gets called.

it's worse than that actually. a dynamic-size matrix still needs to
store a pointer and 2 ints (the dimensions). But when you reserve a
MatrixBase, you reserve only 1 byte, not enough for that data, not too
mention that the dimensions would still need to be initialized as 0 by
the Matrix ctor which doesnt get called.

Benoit


>
> Conclusion: never create explicitly a MatrixBase object, only create
> Matrix objects and then cast them to MatrixBase as needed.
>
> Benoit
>
> 2009/10/30 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
>> Thanks for the report and test-case, that was interesting.
>>
>> First of all, how to make it work with current Eigen: just replace the line
>>   noinit = mat;
>> by
>>   noinit.derived() = mat;
>>
>> Now the reason why your code fails is the following. As you notice,
>>
>>> In general, eigen sets the lhs to the size of the rhs.
>>
>> However, in Eigen, only a Matrix can be resized, the class MatrixBase
>> doesnt have a resize() method (in the devel branch it has one but it
>> still doesn't actually allow to resize).
>>
>> In order to fix that, we would need to make it so that
>> MatrixBase<Derived>::resize() calls Matrix::resize() when the Derived
>> type is Matrix.
>>
>> We can do that with a template helper. I'm asking for opinions here.
>> Should we do that, in order to support Robert's code? If not, then we
>> still must make sure that at least we fail on an assert, not a
>> segfault!
>>
>> Benoit
>>
>>>
>>> This assignment using MatrixBase compiles nicely but fails at run time:
>>> Assertion failed: (rows() == other.rows() && cols() == other.cols()),
>>> function lazyAssign, file
>>> /u/lsst/products/DarwinX86/eigen/2.0.9/include/Eigen/src/Core/Assign.h, line
>>> 406.
>>>
>>> If you use static-sized arrays, you get a SEGV (g++ 4.3.4; os/x 10.6)
>>>
>>> (I care because of the way that SWIG generates code (see yesterday's
>>> problems);  I have almost everything working --- at least if you only want
>>> one type of Eigen arrays (e.g. float, RowMajor) playing with numpy at a
>>> time)
>>>
>>>                                R
>>>
>>>
>>> #include "Eigen/Core.h"
>>>
>>> using namespace Eigen;
>>>
>>> int main() {
>>> #if 0
>>>    MatrixBase<Matrix2f> noinit;
>>>    Matrix2f mat;
>>> #else
>>>    MatrixBase<MatrixXf> noinit;
>>>    MatrixXf mat(2, 2);
>>> #endif
>>>
>>>    noinit = mat;
>>> }
>>>
>>>
>>>
>>>
>>
>



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/