This forum has been archived. All content is frozen. Please use KDE Discuss instead.

passing temporaries of eigen expressions; undefined memory

Tags: None
(comma "," separated)
quantdev
Registered Member
Posts
17
Karma
0
In trying to track down a bug in some code that uses Eigen I've been able to come up with the following simple program which illustrates the issue:

Code: Select all
#include <iostream>
#include <Eigen/Dense>

using Mat = Eigen::Matrix<double, 1, 1, Eigen::AutoAlign>;

template <typename Derived>
auto Modify(const Eigen::DenseBase<Derived>& value)
    -> decltype(2*value.derived().array())
{
    return 2*value.derived().array();
}

Mat Make()
{
    Mat mat;
    mat << 2;
    return mat;
}

int main()
{
    auto mat = Make();

    std::cout
        << "first: " << Modify(mat) << std::endl
        << "second: " << Modify(Modify(mat));

    return 0;
}


The output of this program is:

Code: Select all
first: 4
second: 3.95253e-323


Running the resulting code under valgrind produces a Uninitialised value was created by a stack allocation error.

Is there anything wrong with the above code? As the original mat matrix is in scope at the point where the matrix is evaluated, why does it matter that I'm creating temporaries of Eigen::DenseBase expressions?

I have tried compiling with Eigen 3.2.1 as well as Eigen 3.2.2 and got the same result. I've posted this on Stack Overflow as well.
quantdev
Registered Member
Posts
17
Karma
0
Removing the "array()" calls resolved the issue, as per this answer on stack overflow. If someone could offer a workaround in situations where you don't know the incoming type (ie. you have to assume it is DenseBase) but require array functionality that would be great!

Code: Select all
#include <iostream>
#include <Eigen/Dense>

using Mat = Eigen::Matrix<double, 1, 1, Eigen::AutoAlign>;

template <typename Derived>
auto Modify(const Eigen::DenseBase<Derived>& value)
    -> decltype(2*value.derived())
{
    return 2*value.derived();
}

Mat Make()
{
    Mat mat;
    mat << 2;
    return mat;
}

int main()
{
    auto mat = Make();

    std::cout
        << "first: " << Modify(mat) << std::endl
        << "second: " << Modify(Modify(mat));

    return 0;
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
For the record, there was a shortcoming in ArrayWrapper. Fixed now (the first example does work):

https://bitbucket.org/eigen/eigen/commits/589ff21345fa/
Changeset: 589ff21345fa
User: ggael
Date: 2014-09-10 10:33:19
Summary: ArrayWrapper and MatrixWrapper classes should not be nested by reference.


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell, Yahoo [Bot]