c++eigen3raw-data

Eigen Map is not retaining the actual data provided, it seems to actually copy the data


As I've understood from Eigen::Map official tutorial and documentation, this utilities is provided in order to wrap some raw data with a Eigen structure, without copying the actual underlying data. From the tutorial:

Occasionally you may have a pre-defined array of numbers that you want to use within Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an Eigen type. Fortunately, this is very easy with the Map class.

I've prepared the following very simple code, in which I'm wrapping an Eigen::VectorX around a C++ buffer of 4 float elements:

#include <iostream>
#include <Eigen/Dense>

int main()
{
    const int size = 4;
    float my_array[size]{ 1.0, 2.0, 3.0, 4.0 };
    printf("Original array: ");
    for (int i = 0; i < size; i++) printf("%.1f, ", my_array[i]);
    printf("\n");

    Eigen::ArrayXf eigen_array = Eigen::ArrayXf::Map(&my_array[0], 4, 1);

    printf("Eigen Array: ");
    for (int i = 0; i < size; i++) printf("%.1f, ",eigen_array(i));
    printf("\n");

    printf("Original array address: %0x\n", &my_array[0]);
    printf("Eigen array data address: %0xn\n", eigen_array.data());

    my_array[1] = 10.0;
    printf("Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: %.1f\n", eigen_array(1));

    eigen_array(2) = 20.0;
    printf("Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: %.1f\n", my_array[2]);

    return 0;
}

Built with MSVC 19, Eigen 3.4.90, I get this result, that clearly shows how the array is copied in the new Eigen instance (NOTE: exactly the same happens if I replace ArrayXf with VectorXf, in Debug and Release mode):

Original array: 1.0, 2.0, 3.0, 4.0,
Eigen Array: 1.0, 2.0, 3.0, 4.0,
Original array address: 31cff628
Eigen array data address: b27c4df0n
Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: 2.0
Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: 3.0

Am I missing something? Did I misinterpreted the documentation in some way? Or this is a bug? (I want to think that the problem is on my side, first).


Solution

  • Eigen::ArrayXf::Map works correctly. It does not copy the array. The issue in your code is the conversion to Eigen::ArrayXf that copies the array.

    There is no copy when you use the right type. Let the compier figure it out:

    auto eigen_array = Eigen::ArrayXf::Map(&my_array[0], 4, 1);
    

    Live Demo

    Produces expected output:

    Original array: 1.0, 2.0, 3.0, 4.0, 
    Eigen Array: 1.0, 2.0, 3.0, 4.0, 
    Original array address: d9a99c70
    Eigen array data address: d9a99c70n
    Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: 10.0
    Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: 20.0
    

    (the stray n is from your code, the pointers have identical value)