Return Eigen::VectorXd 通过函数引用

Return Eigen::VectorXd by reference from function

我想从一个函数中 return 一个 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;
}

当然,我们可能会在这里遇到问题,因为在 getMesh() 中用于创建网格向量的内存可能不是动态分配的,即当我们 return 从函数中引用“points”时删除记忆。

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

不得 return 引用您函数的局部变量。这称为。请注意,当您这样做时,您的编译器应该给您一个警告:例如 Visual Studio.

warning C4172: returning address of local variable or temporary: mesh

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

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

这是 VectorXd 定义的示例

class FakeVectorXd {
    int current_size;
    int max_size;
    double* data;
};

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

您可以做的只是按值 return 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;
}