xmemory Line: 141报错,在std::vector容器里装Vector2d等Eigen类型的数据时出错的根本性解决方案

继我昨天发的博客:

  • 标题:报错VC\Tools\MSVC\14.27.29110\include\xmemory Line: 141 Expression: invalid argument解决方案
  • 链接:xmemory报错

里面讲述了我遇到了vector内存问题及当时的解决方案,具体内容可以戳上述链接进入查看。

本来,我以为昨天的解决方案已经很好地解决了这个错误,结果,它(这个错误)就跟鬼火似的,一直跟随着我,所以它今天又找上门来了。这里再贴一下这个错误:

xmemory Line: 141报错,在std::vector容器里装Vector2d等Eigen类型的数据时出错的根本性解决方案
跟昨天一模一样。于是,我就根据昨天的代码优化方法,把今天报错的这一块代码进行了优化。但是,它不管用了(也许是产生了耐药性?哈哈哈开个玩笑)。然后我就百思不得其解,把我能想到的可能有问题的地方都试着改了改,都行不通,于是我已经决定放弃它了,直接趴在桌子上睡起了大觉(直到同机房的师兄们要去吃午饭,我就跟他们一起去了)。转机发生在吃完饭回到机房,我就让昨天一开始没有帮我找到解决方案的那个“另一个师兄”帮我看一下代码(这里可以记昨天帮我解决了问题的师兄为大师兄,然后这个“另一个师兄”为二师兄)。我跟二师兄讲了一下我的思路,具体的debug过程就不赘述了,下面直接说我们找到的引起这个错误的根本性原因:

上代码(截图的是vc路径下的xmemory文件,也就是上面报错的那个文件):
xmemory Line: 141报错,在std::vector容器里装Vector2d等Eigen类型的数据时出错的根本性解决方案
昨天我只截了139 ~ 141行的代码,今天我把整个函数都截下来了,也不长。看函数名以及注释内容,就是和std::vector以及aligned(对齐)有关的。然后再注意到139 ~ 141行,今天我算是读懂了这个报错的意思,就是把没有对齐的vector数据按照对齐的方式进行删除了(可能有点难理解,其实就是139和140这两行注释的字面意思,不过不理解它并不影响你解决这个问题,可以继续往下阅读)。于是二师兄思考了一会儿,说这个可能是eigen的问题,他以前看到过。

然后我们在我报错的这个代码里找到了一个可疑的使用方式:我定义了一个std::vector<Eigen::Vector2d >类型的局部变量,用于存储n个二维点坐标。于是我们从网上搜了一下这种用法,果然,它是有问题的,具体问题的详细解释和解决方法可以参考这个链接。读完后你应该就会对我上面说的用对齐的方式删除没有对齐的vector数据的问题了。因为vector的数据存储方式其实是,它的所有数据在内存中都是连续的,一个接一个地存储,每个数据都有固定的大小。而Eigen有它自己的数据存储方式(至少和std的不太一样),所以当你想要在vector里面嵌入eigen的数据类型的时候,就有可能会报错。下面依据我自己的理解说一下这个报错的原因:

首先回顾一下昨天的博客报错的位置,是在外层for循环结束后报错的,而且每次都是进行一次循环后一出最后面一个“}”时报错。原因就在于,我在外层for循环内声明的std::vector<Eigen::Vector2d >类型的函数局部变量,在循环时,依据eigen自定义的Eigen::Vector2d数据类型一个接一个地存储数据,而在退出这个for循环的时候,系统是以std::vector的方式对这个std::vector<Eigen::Vector2d >局部变量进行内存释放的,而二者的存储释放方式并不一样,所以就产生错误。这也就很好地解释了,每次for循环只能进行一次然后结束后就报错。

这里澄清一下,其实昨天博客里贴的修改前的代码是没问题的,它是siftgpu类型的2d点数据转成opencv类型的2d点数据,这两种类型的二维点存储方式和std的方式是一样的,所以不会出错。出错的其实是我写的另一个将siftgpu类型的二维点转成eigen的vector2d类型特征点的那个函数,当时是因为已经改了这个函数了,且不知道根本原因是eigen,所以就截了尚未修改的一个相同作用的函数而已。不过,昨天的博客当成一个优化代码的方法还是很值得借鉴的。但是,文字描述总还是不如一张图片或者具体代码段演示来得直接(下图就是std::vector<Eigen::Vector2d >的错误使用方式):

xmemory Line: 141报错,在std::vector容器里装Vector2d等Eigen类型的数据时出错的根本性解决方案

其实对于这个问题,我昨天也已经有了解过了,除了上面贴出的一种解决方法外,还有其他的解决方法,比如这个链接,大家只要选择一种适合自己的解决方法即可。