通过函数的引用返回 Eigen::VectorXd

han*_*ndy 3 c++ return eigen

我想从函数返回 Eigen::Vector 并想知道正确的方法是什么。就像是

Eigen::VectorXd& getMesh(int N) {
    Eigen::VectorXd mesh(N + 1);  // nb. of nodes
    // Nodes are equally spaced
    for (int i = 0; i < N + 1; i++) {
        mesh[i] = i * (1.0 / N);
    }

    return mesh;
}

int main() {
    // Mesh with 100 cells
    Eigen::VectorXd mesh = getMesh(100);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,现在我们可能会遇到问题,因为用于在 getMesh() 中创建网格向量的内存可能不会动态分配,即当我们从函数返回时,out 引用“指向”已删除的内存。

我可以在 main 函数内分配内存,然后将其传递给 getMesh 函数,但这可以吗?我还有哪些其他的可能性?

Lou*_*uen 5

不得返回对函数的局部变量的引用。这称为悬空引用。请注意,当您执行此操作时,您的编译器应该向您发出警告:例如 Visual Studio。

warning C4172: returning address of local variable or temporary: mesh
Run Code Online (Sandbox Code Playgroud)

当前函数的问题getMesh()是局部变量mesh在函数执行时在堆栈上分配。然后,您在 中返回对它的引用main,但是当函数退出时,分配的堆栈内存mesh将被释放getMesh()。这意味着它很可能会被程序中的后续数据覆盖。

请注意,即使内存用于存储矢量中存储的坐标,也会发生此问题。您的变量是具有多个成员变量的mesh类 () 的实例。VectorXd其中之一是向量的大小,另一个是指向向量数据动态分配存储的指针。

VectorXd这是定义的示例

class FakeVectorXd {
    int current_size;
    int max_size;
    double* data;
};
Run Code Online (Sandbox Code Playgroud)

创建时mesh,成员变量current_sizemax_sizedata是在堆栈上本地分配的。然后,在向量的构造函数中,data将值设置为指向动态分配的内存区域来存储向量的坐标。当您从 、 和 内存中返回时,堆栈getMesh()位置现在被标记为可用,并且它们将被覆盖。current_sizemax_sizedata

你能做的就是简单地VectorXd按值返回。这完全没问题:

Eigen::VectorXd getMesh(int N) {
    Eigen::VectorXd mesh(N + 1);
    for (int i = 0; i < N + 1; i++) {
        mesh[i] = i * (1.0 / N);
    }
    return mesh;
}
Run Code Online (Sandbox Code Playgroud)

  • 有人可能会提到,按值返回通常是好的,因为[返回值优化](https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization)(忽略了这样一个事实,即 Eigen 有一个内置函数,用于执行OP重新实现)。 (2认同)