Проблема с использованием std :: vector с классом / структурой, содержащей собственные типы, определенные в отдельном файле - PullRequest
0 голосов
/ 12 сентября 2018

EDIT >> заключение, конфликтующие версии Eigen из-за дерьмовой локальной конфигурации?<< </p>

Я пытаюсь определить структуру, которая содержит Eigen :: Matrix.Когда я использую std :: vector и заполняю массив с помощью какой-то функции, происходят странные вещи.

EDIT >> полный исходный код ниже << </p>

Когда я определяю все в одном файле, напримервыше не проблема.Вектор заполняется и возвращается правильно, вызывая size () для доступа к результирующему вектору.(size () = 10).

Когда я определяю типы и функции в отдельных файлах .h и .cpp для основного и делаю то же самое, возвращаемые данные смещаются, так что size () возвращает 12.

Глядя на элементы матрицы, я вижу, что данные сдвигаются на 1 элемент вправо для каждого объекта в векторе.

Единственный способ заставить его работать, когда он определен вотдельный файл должен объявить матрицу как

Eigen::Matrix<float, 4, 4, Eigen::DontAlign> tf

, но я думаю, что это не очень хорошо для эффективности позже.Есть идеи, в чем проблема?Я предполагаю, что это связано с выравниванием матрицы при выделении, но почему это проблема при компиляции / компоновке из разных исходных файлов?

Ubuntu 16.04 gcc 5.4.0 c ++ std 11 Eigen 3.2.1 (предоставленоGTSAM slam package)

РЕДАКТИРОВАТЬ - >>>>

полный исходный код:

key_frames.h

#ifndef __KEY_FRAMES_H__
#define __KEY_FRAMES_H__

#include <Eigen/Dense>

struct test_t {
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    Eigen::Matrix<float, 4, 4> tf;
    int key;
};

void load_test_v(std::vector<test_t,
             Eigen::aligned_allocator<test_t> > & test_vector);
#endif

key_frames.cc

#include <vector>

#include "key_frames.h"

void load_test_v(std::vector<test_t,
             Eigen::aligned_allocator<test_t> > & test_vector){

     for (int i = 0; i < 10; i++) {
     test_t tt;
     tt.tf = Eigen::Matrix4f::Random();
     tt.key = i;
     test_vector.push_back(tt);
    }
 }

opt_key_frames.cc

#include <iostream>

#include <gtsam/geometry/Pose2.h>

#include "key_frames.h"

int main(int argc, const char** argv) {
   std::vector<test_t,
          Eigen::aligned_allocator<test_t> > test_vector;
   test_vector.clear();
   std::cout << "size of test vector " << test_vector.size() << "\n";
   load_test_v(test_vector);
   std::cout << "size of test vector " << test_vector.size() << "\n";
}

Это минимальный воспроизводимый источник.Для сборки я ссылаюсь на библиотеки gtsam.Интересно, если я уберу

#include <gtsam/geometry/Pose2.h>

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

, выведенный из valgrid:

--14269-- REDIR: 0x5c0abb0 (libc.so.6:bcmp) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)
--14269-- REDIR: 0x5cea430 (libc.so.6:__memcmp_sse4_1) redirected to 0x4c33780 (__memcmp_sse4_1)
size of test vector 0
--14269-- REDIR: 0x5c03600 (libc.so.6:posix_memalign) redirected to 0x4c2fd12 (posix_memalign)
size of test vector 12
==14269== 
==14269== HEAP SUMMARY:
==14269==     in use at exit: 72,736 bytes in 2 blocks
==14269==   total heap usage: 259 allocs, 257 frees, 98,174 bytes allocated
==14269== 
==14269== Searching for pointers to 2 not-freed blocks
==14269== Checked 2,634,840 bytes
==14269== 
==14269== LEAK SUMMARY:
==14269==    definitely lost: 0 bytes in 0 blocks
==14269==    indirectly lost: 0 bytes in 0 blocks
==14269==      possibly lost: 0 bytes in 0 blocks
==14269==    still reachable: 72,736 bytes in 2 blocks
==14269==         suppressed: 0 bytes in 0 blocks
==14269== Reachable blocks (those to which a pointer was found) are not shown.

, если удалить gtsam, включите:

--14359-- REDIR: 0x54613b0 (libc.so.6:__GI_mempcpy) redirected to    0x4c34a90 (__GI_mempcpy)
size of test vector 0
--14359-- REDIR: 0x5459600 (libc.so.6:posix_memalign) redirected to 0x4c2fd12 (posix_memalign)
--14359-- REDIR: 0x54564f0 (libc.so.6:free) redirected to 0x4c2ec69 (free)
size of test vector 10
==14359== 

Так что там что-то меняется.

Вывод: моя установка испорчена.Я подозреваю, что включение Eigen / Dense предназначено для всей установленной системы Eigen3.3.Хотя GTSam использует Eigen 3.2, поставляемый с пакетом, и по какой-то причине мои локальные настройки приводят их в замешательство, тогда как когда я запускаю код в другом каталоге, только GTSam Eigen привыкает.

В любом случае спасибо заПомогите.Работая через это, помог мне понять.

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