有以下代码段错误的明显原因吗?
#include <vector>
#include <emmintrin.h>
struct point {
__m128i v;
point() {
v = _mm_setr_epi32(0, 0, 0, 0);
}
};
int main(int argc, char *argv[])
{
std::vector<point> a(3);
}
Run Code Online (Sandbox Code Playgroud)
谢谢
编辑:我在linux/i686上使用g ++ 4.5.0,我可能不知道我在做什么,但是因为甚至以下的段错误
int main(int argc, char *argv[])
{
point *p = new point();
}
Run Code Online (Sandbox Code Playgroud)
我真的认为它必须和对齐问题.
在gcc或clang(或任何其他编译器)中是否有一种方法可以吐出有关结构是否有空洞(内存对齐方式)的信息?
谢谢.
ps:如果还有其他办法,请告知我.
简介:编译期间编译器如何静态地确定C++类的大小?
细节:
我试图了解规则用于确定类将使用多少内存,以及内存如何对齐.
例如,以下代码声明了4个类.前2个是16个字节.但是3是48个字节,即使它包含与前2个相同的数据成员.而第四个类具有与第三个相同的数据成员,只是以不同的顺序,但它是32个字节.
#include <xmmintrin.h>
#include <stdio.h>
class TestClass1 {
__m128i vect;
};
class TestClass2 {
char buf[8];
char buf2[8];
};
class TestClass3 {
char buf[8];
__m128i vect;
char buf2[8];
};
class TestClass4 {
char buf[8];
char buf2[8];
__m128i vect;
};
TestClass1 *ptr1;
TestClass2 *ptr2;
TestClass3 *ptr3;
TestClass4 *ptr4;
int main() {
ptr1 = new TestClass1();
ptr2 = new TestClass2();
ptr3 = new TestClass3();
ptr4 = new TestClass4();
printf("sizeof TestClass1 is: %lu\t TestClass2 is: %lu\t TestClass3 is: …Run Code Online (Sandbox Code Playgroud) 我有项目我从32位窗口移植到64位,其中包括可简化如下的代码;
void FuncA(double &x)
{
x = 0;
}
void FuncB(double *x)
{
*x = 0;
}
#pack(1)
struct
{
char c;
double x;
} MyStruct;
#pack();
void MyFunc()
{
MyStruct M;
FuncA(M.x); // This is OK
FuncB(&M.x); // This generates a warning C4366
}
Run Code Online (Sandbox Code Playgroud)
在针对64位的VS2010 SP1下进行编译时FuncB,使用压缩结构的成员进行调用会生成以下警告;
警告C4366:一元'&'运算符的结果可能是未对齐的
虽然打电话FuncA没有.我原以为这两种情况都会编译成几乎相同的代码.引用在某些方面比对等指针更安全吗?或者MSVC根本不发出警告应该在哪里?该项目需要维护结构包装,因此我的选择是要么FuncB改为
void FuncB(__unaligned double *x)
{
*x = 0;
}
Run Code Online (Sandbox Code Playgroud)
或者只是FuncA在所有这些情况下使用.后者是更好的,因为它更便携,但我想知道它是否会起作用或者在参考案例中缺少警告只是编译器中的一个缺点.
编辑: 此错误的Microsoft帮助条目在这里.该__unaligned帮助表明,没有理会这一警告会导致异常要在安腾处理器抛出.围绕MSDN的进一步拖网表明,可能存在围绕未对齐引用的问题.虽然这可能不会给我当前的用户带来问题,但如果Itanium架构在未来得到更广泛的使用,我可能会设置一个支持噩梦.Plan现在是为使用压缩结构的所有函数添加特定包装器,以避免使用指针和__unaligned关键字.
我需要在Rust中将结构与16字节边界对齐.似乎可以通过repr属性给出关于对齐的提示,但它不支持这个确切的用例.
什么我想要实现的功能测试是一种Foo这样
assert_eq!(mem::align_of::<Foo>(), 16);
Run Code Online (Sandbox Code Playgroud)
或者,具有这样Bar的字段的结构baz
println!("{:p}", Bar::new().baz);
Run Code Online (Sandbox Code Playgroud)
始终打印一个可被16整除的数字.
这在Rust当前有可能吗?有没有解决方法?
我试图理解为什么只包含 int 的结构在类中占用 8 个字节的内存。
考虑以下代码;
static void Main()
{
var rand = new Random();
var twoIntStruct = new TwoStruct(new IntStruct(rand.Next()), new IntStruct(rand.Next()));
var twoInt = new TwoInt(rand.Next(), rand.Next());
Console.ReadLine();
}
public readonly struct IntStruct
{
public int Value { get; }
internal IntStruct(int value)
{
Value = value;
}
}
public class TwoStruct
{
private readonly IntStruct A;
private readonly IntStruct B;
public TwoStruct(
IntStruct a,
IntStruct b)
{
A = a;
B = b;
}
}
public class …Run Code Online (Sandbox Code Playgroud) 是否有一个属性可以在变量后强制填充?
我有一个易失性(非缓存)变量声明如下:
volatile int foo __attribute__((aligned(CACHE_LINE_SIZE));
Run Code Online (Sandbox Code Playgroud)
我想防止其他变量分配到同一缓存行,以避免一致性问题。我可以在 foo 之后添加一个填充变量,或者将其设置__attribute__((aligned(CACHE_LINE_SIZE))为同一编译单元中的以下变量。但是我想知道是否有更干净的方法来执行此操作,例如向变量foo本身添加属性以强制填充。
我最近在应用程序中遇到了我认为是错误共享的问题,我查阅了Sutter关于如何将数据与缓存行对齐的文章.他建议使用以下C++代码:
// C++ (using C++0x alignment syntax)
template<typename T>
struct cache_line_storage {
[[ align(CACHE_LINE_SIZE) ]] T data;
char pad[ CACHE_LINE_SIZE > sizeof(T)
? CACHE_LINE_SIZE - sizeof(T)
: 1 ];
};
Run Code Online (Sandbox Code Playgroud)
我可以看到当这CACHE_LINE_SIZE > sizeof(T)是真的时它会如何工作- 结构cache_line_storage最终会占用一个完整的内存缓存行.但是,当sizeof(T)大于单个缓存行时,我认为我们应该按CACHE_LINE_SIZE - T % CACHE_LINE_SIZE字节填充数据,以便生成的结构的大小是缓存行大小的整数倍.我的理解有什么问题?为什么填充1个字节就足够了?
我一直在使用Valgrind来查找我的代码中的内存泄漏,虽然没有发现内存泄漏,但是报告了一些错误,它们全部来自单个函数/类方法:
==17043== ERROR SUMMARY: 10100 errors from 3 contexts (suppressed: 0 from 0)
==17043==
==17043== 100 errors in context 1 of 3:
==17043== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==17043== at 0x5441DA2: send (send.c:28)
==17043== by 0x404C2D: unix_socket::sendMsg(char, double) (in /home/joao/CloudPT/Bolsa/Webots/controllers/darwin-pi2/client)
==17043== by 0x404F1C: unix_socket::sendVectorXd(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&) (in /home/joao/CloudPT/Bolsa/Webots/controllers/darwin-pi2/client)
==17043== by 0x401F2A: main (in /home/joao/CloudPT/Bolsa/Webots/controllers/darwin-pi2/client)
==17043== Address 0x7feffff61 is on thread 1's stack
==17043== Uninitialised value was created by a stack allocation
==17043== …Run Code Online (Sandbox Code Playgroud) (提前抱歉没有设法将我的问题减少到简单的失败测试用例...)
我遇到了升级到GCC 6.3.0以构建我们的代码库(相关标志:)的问题-O3 -m32.
具体来说,由于GCC优化,我的应用程序会在struct ctor调用中进行段错误.
在这个ctor中,GCC使用了movaps:
movaps %xmm0,0x30a0(%ebx)
Run Code Online (Sandbox Code Playgroud)
movaps 要求操作数为16字节对齐.但是在这个时间%ebx点,指向我的对象,不一定是16字节对齐.来自glibc:
"在GNU系统中,malloc或realloc返回的块的地址总是八的倍数(或64位系统上的十六个)."
因此segfault(建立时-O3 -m32).
为什么GCC假设分配的对象是16字节对齐?我误会了什么吗?
笔记:
new运算符初始化-m32 -O2-m32 -O2 -ftree-slp-vectorize-m32 -O3 -fno-tree-slp-vectorize-m32 -O3这个其他项目似乎遇到了类似的问题:https://github.com/godotengine/godot/issues/4623
他们的调查指向-fvect-cost-model=dynamic.调查我的代码库而不是指向-ftree-slp-vectorize.