STL无序映射使用uum128值崩溃
我跟踪了一个bug,在std::unordered\u映射中将uu m128(SSE向量)用作值。 这会导致mingw32 g++4.7.2出现运行时分段错误 请参见下面的示例。 这有什么理由失败吗? 或者,可能有解决办法吗?(我尝试在类中包装该值,但没有帮助。) 谢谢STL无序映射使用uum128值崩溃,stl,sse,unordered-map,Stl,Sse,Unordered Map,我跟踪了一个bug,在std::unordered\u映射中将uu m128(SSE向量)用作值。 这会导致mingw32 g++4.7.2出现运行时分段错误 请参见下面的示例。 这有什么理由失败吗? 或者,可能有解决办法吗?(我尝试在类中包装该值,但没有帮助。) 谢谢 #包括 #包括//uu m128 #包括 int main() { std::无序映射m; 标准::cerr关于校准有两个问题: ABI是否确保堆栈上的变量始终对齐 全局new运算符是否返回与\uum128类型适当对齐的内存?即
#包括
#包括//uu m128
#包括
int main()
{
std::无序映射m;
标准::cerr关于校准有两个问题:
ABI是否确保堆栈上的变量始终对齐
全局new
运算符是否返回与\uum128
类型适当对齐的内存?即,返回16字节对齐的内存。C++当前不处理过度对齐类型的动态分配。对于常见的x86 ABI,标准对齐是8,而\uum128具有16字节的对齐,因此它是过度对齐的。对于我们在ual x86_64 ABIs中,标准对齐方式为16,这使得uuu m128安全(但uuu m256的32字节对齐方式同样不安全)
请参阅本文,了解下一个标准中可能的变化,这将使事情“正常工作”:
同时,您可以指定自己的分配器,例如基于aligned_alloc(C11)、posix_memalign(unix)、aligned_malloc(Microsoft)等等。这里的一些相关阅读:当您取消引用指向\uuum128
类型的指针时,编译器发出的结果加载/存储函数通常是对齐的,因此它假设底层内存按照类型的需要对齐(本例中为16字节对齐)。我猜在容器代码中的某个地方,指向\uuu m128
的指针正在被取消引用,对齐假设不成立,从而导致分段错误。如果您使用调试器运行程序并在崩溃后检查指针值,您应该能够看到这一点。难道没有访问m[0]的权限吗
是否仍有未定义的行为?我希望访问m[0]
并不特别;我在整个代码中都使用它;您是否有任何指针建议保留key==0
?感谢您的反馈;这肯定是一个对齐问题。似乎STL容器的设计应该尊重元素的对齐属性。现在可能需要自定义m内存分配器?
#include <unordered_map>
#include <xmmintrin.h> // __m128
#include <iostream>
int main()
{
std::unordered_map<int,__m128> m;
std::cerr << "still ok\n";
m[0] = __m128();
std::cerr << "crash in previous statement\n";
return 0;
}