2017-02-21 24 views
5

Próbuję przejąć na własność pamięć wspierającą Eigen::Matrix bez kopiowania pamięci. Metoda data() zachowuje własność. Jedynym sposobem mam zorientowali się, jak to zrobić jest odwzorowany przez zamianę tablicy:Uzewnętrznianie danych z macierzy Eigen

Matrix<float, Dynamic, Dynamic, RowMajor> mat = m1 * m2; 
// want ownership of mat's float* 

float* data = mat.data(); // get the pointer 
new (&mat) Eigen::Map<Matrix3f>(NULL); // swap the mapped array with anything else 
// do something with data 

To nie wygląda to powoduje kopię pod maską, ale nie jestem pozytywne. Nie jestem też pewien, czy to jest bezpieczne.

+0

Dlaczego po prostu nie utrzymywać obiektu matrycy Eigen przy życiu, gdy potrzebujesz jego danych? – rubenvb

+0

@rubenvb Muszę przekazać dane do innego środowiska, w którym nie mam takiej kontroli. – ZachB

+0

To bardzo niejasne stwierdzenie. Nadal nie widzę problemu z utrzymaniem obiektu Eigen przy życiu, podczas gdy inne środowisko robi to samo. – rubenvb

Odpowiedz

3

Oderwanie pamięci od wnętrzności Eigen jest niegrzeczne, nie najmniej ważnym z nich, ponieważ nie wiesz, w jaki sposób został przydzielony lub co jeszcze posiadał Matryca.

Istnieje jednak Map template, który pozwala owinąć nieposiadany bufor w typ podobny do macierzy macierzy.

Ten typ nie jest rzeczywistą matrycą wektorów, więc twoje własne funkcje niestandardowe mogą z nią nie działać, ale powinno działać z funkcjami Eigen.

W tym przypadku użytkownik jest już właścicielem danych.

using matrix_type = Matrix<float, Dynamic, Dynamic, RowMajor>; 
using mapped_matrix_type = Map<matrix_type>; 

Teraz tworzymy bufor, zawinąć je w mapped_matrix_type i przypisać:

auto raw = std::make_unique<float[]>(m1.rows()*m2.cols()); // maybe backwards 
mapped_matrix_type bob(raw.get(), m1.rows(), m2.cols()); 
bob = m1*m2; 

surowe dane z bob jest w raw, a unique_ptr własnością bufor (które mogą release() jeśli trzeba aby całkowicie go wyłączyć).

Dowolny surowy mechanizm magazynowania (vector, surowy new, cokolwiek innego) może zająć miejsce raw.

Kod nie testowany.