2014-10-06 1 views
6

저는 소프트웨어에서 Eigen을 사용하고 있으며, 코드를 정적 라이브러리를 만드는 것으로부터 동적 라이브러리로 변경하여 발생했습니다. Windows에서 Visual Studio 2013을 사용합니다.이 스위치의 원인은 Eigen과 관련이 없었습니다.Visual Studio 2013에서 동적 라이브러리와 함께 Eigen을 사용하여 메모리 정렬 오류가 발생했습니다.

저는 자체 라이브러리 파일에 Eigen을 임베드하고 있습니다. 그 자체가 내 응용 프로그램에 연결됩니다. 앞서 언급했듯이이 라이브러리는 오늘날까지 정적 라이브러리였습니다. 방금 DLL 파일을 생성하도록 코드베이스를 업데이트했습니다.

이 변경하기 때문에, 지금의 Visual Studio에서 다음과 같은 오류 메시지가 점점 오전 :

블록 --------------------에 있었다 정렬 된 루틴에 의해 할당 된

(이 메시지는 매번 다른 주소로 여러 번 나타납니다. 특정 주소가이 문제와 관련이 있다고 생각하지 않으므로 위의 대시를 사용했습니다.). "재시도"선택

EIGEN_ALIGN 및 EIGEN_HAS_MM_MALLOC가 모두 1 EIGEN_MALLOC_ALREADY_ALIGNED 및 EIGEN_HAS_POSIX_MEMALIGN 모두 정의되지로 정의 제안 Memory.h

비주얼 스튜디오 인텔리 (디버깅 생략)에 255 행으로 디버거를 연다. 따라서 _mm_free (ptr)가 실행 중이어야하며 (IntelliSense에서 다시 기반) _aligned_free (a)의 별칭입니다. 따라서이 코드는 올바른 기능을 실행해야하지만 그렇지 않습니다.

코드를 다시 정적 라이브러리로 변경하면이 문제가 해결됩니다.

내가 여러 가지 Google 검색에서 찾은 유일한 것은 인텔 포트란 컴파일러의 기사에 따르면이 오류 메시지는 최신 버전으로 컴파일 된 코드에 의해 호출 된 이전 버전에서 컴파일 된 라이브러리에서 가져온 것일 수 있습니다 . 사실 Visual Studio C++ 2013을 사용하고 있다는 사실 외에도 코드가 여러 번 재 빌드되어 모두 깨끗한 상태에서 완전히 다시 컴파일되고이 오류 메시지가 계속 발생합니다.

mercurial repo (기본 분기)에서 최신 코드를 다운로드했지만 문제가 해결되지 않았습니다.

나는 최대한 철저 해 지려고 노력했다. 더 자세한 정보가 필요하면 알려주십시오.

편집 :

또한 컨텍스트 :

이 경우 DLL을 이용하는 '클라이언트 코드는'구글 테스트입니다 기대를 테스트 한 후에 오류 메시지가 발생합니다. 즉 DLL 파일의 클래스가 임시 객체를 정리하기 위해 소멸자를 실행하고 있습니다. DLL 파일에서 메모리를 할당 한 다음 드라이버 응용 프로그램에서 메모리를 할당 해제하는 것과 같은 악의적 인 작업을 시도하지 않습니다. 그 이유 중 일부는 너무 혼란 스럽습니다 ...

+0

DLL과 DLL을 사용하는 클라이언트가 같은 빌드되었는지 확인하십시오? 내가 큰 소리로 생각하고있어 - DLL이 mallocs를하고 있으며 한 가지 방법으로 해제하고 클라이언트가 다른 일을 할 수 있다는 것이 분리되어 있습니다. 보통 이런 이유로 클라이언트가 DLL에서 생성 된 객체를 무료로 호출하는 것은 바람직하지 않습니다. 일반적으로 클린업 (즉, 무료) 루틴을 DLL에서 내보내 클라이언트가 직접 호출하지 않고 호출 할 수 있도록합니다. 객체 생성에 대해서도 마찬가지입니다. –

+0

@MichaelPetch 나는 그들이 같은 것을 만들었다는 것을 확신한다. 물론 DLL과 정적 라이브러리는 동일합니다 (한 설정 만 변경합니다). 또한 - 나는 클라이언트에서 무료로 전화하지 않을거야 - 문제의 코드는 DLL을 정리 코드입니다. 필자의 경우 클라이언트는 라이브러리의 코드에 대한 단위 테스트를 실행하는 Google Test입니다. 일시적인 고유 행렬 소멸자가 호출되어야하는 지점에서 중단 점에 도달합니다. 나는 질문을 업데이트하고 다른 사람들의 이익을 위해이를 분명히 할 것이다. 전에는 명확하지 않았 음을 알 수 있습니다. –

답변

2

이 정확한 문제가 있습니다. . Eigen을 DLL로 사용하는 정적 라이브러리를 변환하여 gtest로 단위 테스트를 할 때 이러한 오류가 발생하기 시작했습니다. 해결책이 없으므로 문제를 해결하기 위해 내가 한 일을 제공 할 것입니다. 본질적으로 문제는 Eigen 행렬/벡터가 멤버 변수로 포함 된 클래스에 대한 새 인터페이스를 만들고 해당 인터페이스가 Eigen 멤버 변수가있는 클래스에 대한 포인터를 만드는 것입니다.

첫째, 고유 변수 또는 벡터 인 멤버 변수가 있다면 this을 읽어야합니다. 요약하면 당신은

대중을 추가해야합니다 : 당신은 멤버 변수로 아이겐를 사용하여 클래스 정의에 EIGEN_MAKE_ALIGNED_OPERATOR_NEW

합니다. Visual Studio 컴파일러를 사용하는 경우 warning C4316: object allocated on the heap may not be aligned 16에 대한 경고가 표시 될 수도 있습니다.

이제 EIGEN_MAKE_ALIGNED_OPERATOR_NEW을 사용한 후에도 문제가 발생했습니다. 이는 고유 한 행렬 클래스를 사용하여 원자를 사용했기 때문입니다. boost::atomic<Eigen::MatrixXf>을 멤버 변수로 사용합니다. 원 자성을 보장 할 때 정렬이 매우 중요하다고 생각합니다.