Re: [eigen] Assignment to MatrixBase fails assertion or SEGVs |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Assignment to MatrixBase fails assertion or SEGVs
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Fri, 30 Oct 2009 18:00:36 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=BYoH0IO0BaYPER3sX3fHvurm8b6wPNKY3UclojQw1nw=; b=rwfY/9IWWs/4Er9kdqsFwkh1hwelhaxtTNDPI14a1iFvpv1cYvq8/py8F1BBeucoDO VtsUKl0JLF0VSEjSI6vURw1MDoF81SLZwQqryuNQXJamsjJSt8++42w200aizvn0209G 1NvLgk/1Y++EVGz2o+6KxX8diDqNC/6rDTRtk=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=JHsew9l2l3UsK8M82+/UvGrU8D4hvIfv0D3KW6noRkmucYFSYQwC9aVBwQd/v72ebn I6YbX0y80rbrfil/rkdHL56xSdiCWvwtIUsgO+/w/X4vbCJwAoIrVbut0W9KrJbwwZLc 7wkiSxJDchaUhITcedjUaBp1jsnQDkVIdkowk=
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;
>>> }
>>>
>>>
>>>
>>>
>>
>