I have the following issue when compiling in release mode
using MSVC 19.31.31106.2
(and C++17, as far as I understand the eigen page, alignment should be not an issue anymore) that I get a segfault
from within of std::sort
.
The official Eigen 3.4
release is used.
The following compiler flags are set:
/errorReport:prompt /WX /Zc:forScope /GR /arch:AVX2 /Gd /MD /std:c++17 /GS /W4 /wd"4389" /wd"4996" /wd"4244" /wd"4324" /wd"4127" /Zc:wchar_t /EHsc /nologo /Gm- /O2 /Ob2 /Zc:inline /fp:precise /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_CRT_SECURE_NO_WARNINGS"
So I have the following struct:
struct MyStruct
{
Eigen::Matrix<double, 2, 1> mVecA{};
Eigen::Matrix<double, 2, 1> mVecB{};
bool mA = true;
uint64_t mB = 0;
};
Then after filling a vector std::vector<MyStruct> myVec;
with some data the call to
std::sort(myVec.begin(), myVec.end(), [](const MyStruct& lhs, const MyStruct& rhs) { return lhs.mB < rhs.mB; });
causes a segfault (whereas using std::stable_sort
causes no issue) it seems to be thrown from inside of std::move
. In debug mode this does not happen.
Further when changing the order of MyStruct
to
struct MyStruct
{
bool mA = true;
uint64_t mB = 0;
Eigen::Matrix<double, 2, 1> mVecA{};
Eigen::Matrix<double, 2, 1> mVecB{};
};
the segfault does not appear anymore at all. I don't really understand why this order would be an issue? Shouldn't it also be preferable to avoid unecessary padding within the struct?
Another thing that could fix it would be to explicitly defie alignment for the eigen matrices:
struct MyStruct
{
alignas(32) Eigen::Matrix<double, 2, 1> mVecA{};
alignas(32) Eigen::Matrix<double, 2, 1> mVecB{};
bool mA = true;
uint64_t mB = 0;
};
Here is a minimal example (AVX2 is enabled in the CMake and Eigen needs to be included): Here is an godbolt example: https://godbolt.org/z/odned4axW. (It only works when /MD
is not added to the flags, otherwise it will not run at all.. which is different from the behaviour on my local machine, where it can still run with /MD
but causes an exception in the move
constructor)
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/StdVector>
#include <stdint.h>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
int main()
{
struct MyStruct
{
MyStruct() = default;
MyStruct(const Eigen::Matrix<double, 2, 1>& vecA, const Eigen::Matrix<double, 2, 1>& vecB, uint64_t value, bool boo) : mVecA(vecA), mVecB(vecB), mValue(value), mBool(boo) {}
alignas(32) Eigen::Matrix<double, 2, 1> mVecA{};
alignas(32) Eigen::Matrix<double, 2, 1> mVecB{};
uint64_t mValue = 0;
bool mBool = true;
};
std::vector<MyStruct> mSorted;
for (uint64_t i = 0; i < 1000; i++)
mSorted.emplace_back(Eigen::Matrix<double, 2, 1>::Random(), Eigen::Matrix<double, 2, 1>::Random(), static_cast<uint64_t>(rand()), true);
std::sort(mSorted.begin(), mSorted.end(), [](const MyStruct& lhs, const MyStruct& rhs) { return lhs.mValue < rhs.mValue; });
std::cout << mSorted[0].mValue << std::endl;
std::cout << "Super test" << std::endl;
}
The error occurs in PlainObjectBase.h
line 496 (move constructor of PlainObjectBase
) traced from (std::sort
-> std::_Sort_unchecked
-> std::_Partition_by_median_guess_unchecked
-> std::iter_swap
-> std::swap
).
alignas(32)
is removed the crash happens otherwise it runs fine for me. – Buddhi/MD
parameter makes it work: godbolt.org/z/s3KxzEsGa (No idea/didn't look up what that does). – AretinaMD
does dynamic runtime linkage./MT
links runtime statically. It is not a good idea to mix libraries with different runtime linkage. For instance, one could pass an allocated object to another unit that uses a different runtime. Upon destruction the other allocator might deallocate a memory address which it does not have an access to (hence Segmentation Fault) – Wallboardstd::swap
). – Buddhi/MD
and gives output for me. But with/MD
i cannot get it to run at all (this behaviour seems different from my local machine) – Buddhi/MD
does not run: The returned error code 3221225781 is 0xC0000135 in hex, meaningSTATUS_DLL_NOT_FOUND
. Apparently, a necessary library is not installed there? – Advocaat