Распределение памяти вектора внутри функции при построении матриц с помощью Eigen :: Map - PullRequest
0 голосов
/ 30 марта 2020

Я создал класс, который читает вектор и копирует результат в нужную матрицу (фактически он заменяет строку на вектор, а анализируемый вектор имеет неизвестный размер, но я публикую упрощенный код).

Функция getMatrix читает вектор, копирует его в вектор containerVector и, используя функцию Map, преобразует его в матрицу containerMatrix, передавая по ссылке. Однако после выполнения функции объект containerVector уничтожается, так что, насколько я понимаю, учебник Eigen Map , containerMatrix указывает на никуда (или на какое-то случайное место в памяти). Поэтому, когда я выполняю вторую функцию setModelMatrix, она должна либо возвращать некоторую ошибку выделения памяти или ошибки сегментации. Тем не менее, он работает должным образом, поэтому похоже, что значения были скопированы, а не переданы. Безопасно ли использовать Карту таким образом, или мне просто повезло? Правильно ли мое понимание или есть лучшее решение?

Примечание: я буду использовать функцию getMatrix несколько раз для разных векторов и скопировать полученные значения в разные матрицы, которые не включены в представленную часть кода. Инициализатор запятой не работал для моей проблемы.

class MatrixModificationClass
{
 private:
 //two matrices defined
    MatrixXd containerMatrix; //a container
    MatrixXd modelMatrix;   //the proper matrix

 public:
    MatrixModificationClass();

//a function to create vector and map it to matrix 
 void getMatrix(std::vector ivector)
 { 
  std::vector<double> containerVector;
  //This is only a simplified example, in reality I change string to a vector
  containerVector=ivector; 
  int instances=10, columns=10;  //size of matrix

  containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);
  containerMatrix.transposeInPlace();
 };   

 void setModelMatrix()
 {
     modelMatrix = containerMatrix;
 };
};

main()
{
 std::vector newVector;
 MatrixModificationClass Example;
  for (int i = 1; i <= 100; i++) 
   newVector.push_back(i);
 Example.getMatrix(newVector);
 Example.setModelMatrix();
}

1 Ответ

1 голос
/ 31 марта 2020

Ваш код безопасен (хотя и неоптимален).

В этой строке

containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);

Создается объект Eigen::Map, который указывает на &containerVector[0], а затем его содержимое. копируются в containerMatrix (объект MatrixXd всегда владеет своими данными). Затем Eigen::Map уничтожается (он выходит за рамки ;), а containerVector уничтожается только в конце метода.

В качестве простой оптимизации вы можете избежать transposeInPlace(), непосредственно присваивая

containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances).transpose();

В зависимости от того, как вы «измените строку на вектор», вы, вероятно, могли бы напрямую записать в containerMatrix (вам нужно изменить размер до правильных размеров, прежде чем делать это) , Вы также можете хранить containerVector внутри своего класса (вместо containerMatrix) и создавать Eigen::Map на лету, когда вам это нужно. Однако наиболее эффективное решение зависит от вашего фактического варианта использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...