将 Eigen 与 Visual Studio 2013 的动态库一起使用的内存对齐错误
Posted
技术标签:
【中文标题】将 Eigen 与 Visual Studio 2013 的动态库一起使用的内存对齐错误【英文标题】:Memory alignment errors using Eigen with a dynamic library with Visual Studio 2013 【发布时间】:2014-10-06 19:18:46 【问题描述】:我一直在我的软件中使用 Eigen,但我今天遇到了一个问题,这是由于使用 Visual Studio 2013 将我的代码从在 Windows 中构建静态库更改为动态库引起的。此切换的原因是与本征无关。
我将 Eigen 嵌入到我自己的库文件中,然后将其链接到我的应用程序中。如前所述,该库直到今天一直是静态库;我刚刚更新了我的代码库以生成一个 DLL 文件。
自从进行此更改后,我现在从 Visual Studio 收到以下错误消息:
--------------------处的块是由对齐的例程分配的,使用_aligned_free()
(这条消息每次都会以不同的地址弹出无数次;我在上面使用了破折号,因为我不认为具体的地址与这个问题有关)。
选择“重试”将调试器打开到 Memory.h 上的第 255 行
Visual Studio IntelliSense(未调试时)建议 EIGEN_ALIGN 和 EIGEN_HAS_MM_MALLOC 均定义为 1,EIGEN_MALLOC_ALREADY_ALIGNED 和 EIGEN_HAS_POSIX_MEMALIGN 均未定义。因此,它应该运行 _mm_free(ptr),它(再次基于 IntelliSense)是 _aligned_free(a) 的别名。因此,这段代码似乎应该运行正确的函数,但事实并非如此。
当我将代码改回静态库时,这个问题就消失了。
我从众多 Google 搜索中发现的唯一与远程相关的内容是来自 Intel Fortran Compiler 的一篇文章,该文章称此错误消息可能来自在较早版本中编译的库,该库由使用最新版本编译的代码调用。除了我使用的是 Visual Studio C++ 2013 之外,我已经多次重建代码以确保它完全从干净状态重新编译并且此错误消息仍然存在。
我已经从 mercurial repo(默认分支)下载了最新的代码,但这并没有解决问题。
我尽量做到彻底。如果您需要更多信息,请告诉我。
编辑:
进一步的背景:
在这种情况下使用 DLL 的“客户端代码”是 Google Test;测试期望后引发错误消息 - 即 DLL 文件中的类正在运行析构函数以清理临时对象。我并没有试图做一些邪恶的事情,比如在 DLL 文件中分配内存,然后在驱动程序应用程序中取消分配——这就是我觉得这很令人困惑的部分原因......
【问题讨论】:
你确定 DLL 和使用 DLL 的客户端构建的相同吗?我正在大声思考——现在 DLL 正在执行 malloc 并以一种方式释放并且客户端可能正在执行其他操作是分开的。通常由于这个原因,客户端在 DLL 中创建的对象上调用 free 并不是一个好习惯。通常,您从 DLL 导出清理(即免费)例程,以便客户端可以调用这些例程,而不是直接执行它。对象创建也是如此。 @MichaelPetch 我很确定它们的构造是一样的。当然 DLL 和静态库是相同的(我只更改了一个设置)。另外 - 我不是从客户端免费调用 - 有问题的代码是 DLL 清理代码。就我而言,客户端是 Google Test,它正在对库中的代码运行单元测试;在应该调用临时 Eigen 矩阵析构函数的点处到达断点。为了他人的利益,我将更新问题并澄清这一点。我看到这之前不清楚。 【参考方案1】:我有这个确切的问题。我将使用 Eigen 的静态库转换为 DLL,并在使用 gtest 进行单元测试时开始出现这些错误。由于没有解决方案,我将提供解决问题的方法。本质上,问题在于您已经为包含特征矩阵/向量作为成员变量的类创建了一个新接口,并且该接口使用您的特征成员变量创建了指向该类的指针。
首先,如果您的成员变量是特征矩阵或向量,那么您应该阅读this。总之,您需要添加
公开: EIGEN_MAKE_ALIGNED_OPERATOR_NEW
到您使用 Eigen 作为成员变量的类定义。如果您使用 Visual Studio 编译器,大概还会收到有关 warning C4316: object allocated on the heap may not be aligned 16
的警告。
现在,我在使用EIGEN_MAKE_ALIGNED_OPERATOR_NEW
后仍然遇到问题,这是由于将 atomic 与 Eigen 矩阵类一起使用; boost::atomic<Eigen::MatrixXf>
作为成员变量。我认为在保证原子性时对齐非常重要。
【讨论】:
以上是关于将 Eigen 与 Visual Studio 2013 的动态库一起使用的内存对齐错误的主要内容,如果未能解决你的问题,请参考以下文章
Eigen 程序无法从 Visual Studio 编译,但从命令行编译成功
在 Visual Studio c++ 项目中将 Eigen 外部库放在哪里?
Visual Studio 2017 发行版中的 Eigen cwisemin/cwisemax 访问冲突
如何在 Visual Studio 2015 中添加库、头文件