标签: memory-alignment

未对齐的内存访问是否总是导致总线错误?

根据维基百科页面分段错误,未对齐的内存访问可能导致总线错误.本文提供了有关如何触发总线错误的示例.在该示例中,我们必须启用对齐检查以查看总线错误.如果我们禁用这种对齐检查怎么办?

该程序似乎正常工作.我有一个程序经常访问未对齐的内存,并且它被很多人使用,但没有人向我报告总线错误或其他奇怪的结果.如果我们禁用对齐检查,未对齐内存的副作用是什么?

平台:我正在开发x86/x86-64.我也通过在Mac上用"gcc -arch ppc"编译它来尝试我的程序,它运行正常.

c memory-alignment

9
推荐指数
2
解决办法
6915
查看次数

哪里可以找到跨不同平台/编译器的C++内存对齐文档?

我正在寻找一个关于C++内存对齐的好(全面)文档,典型方法,编译器之间的差异以及常见的陷阱.只是为了检查我对这个主题的理解是否正确并学习新的东西.

这个问题的灵感来自于我使用以下构造的另一个问题的答案:

char const buf[1000] = ...;
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything
Run Code Online (Sandbox Code Playgroud)

它被批评为不符合内存对齐规则.你可以解释为什么这种方法从内存对齐的角度来看是有缺陷的?一个不起作用的例子将受到高度赞赏.我知道这通常是一种糟糕的方法,但我经常在网络协议实现中使用它,所以它比理论问题更实际.

另外请不要在这里提到严格别名,这是另一个问题.

c++ memory-alignment

9
推荐指数
2
解决办法
423
查看次数

为什么struct的大小需要是任何struct成员的最大对齐的倍数

我理解结构成员之间发生的填充,以确保各个类型的正确对齐.但是,为什么数据结构必须是最大成员对齐的倍数?我不明白最后需要填充.

参考:http: //en.wikipedia.org/wiki/Data_structure_alignment

c++ memory-alignment

9
推荐指数
1
解决办法
1172
查看次数

为PInvoke正确声明SP_DEVICE_INTERFACE_DETAIL_DATA

SP_DEVICE_INTERFACE_DETAIL_DATA结构:

typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
  DWORD cbSize;
  TCHAR DevicePath[ANYSIZE_ARRAY];
} SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA;
Run Code Online (Sandbox Code Playgroud)

如何在C#中声明它才能Marshal.SizeOf正常工作?

我没有分配动态缓冲区的问题.我只想以cbSize适当的,非硬编码的方式进行计算.

PInvoke.net定义是错误的.
PInvoke.net的解释也是错误的:

SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :)
Run Code Online (Sandbox Code Playgroud)

不要相信他.
4 + Marshal.SystemDefaultCharSize仅在x86上有效.同样的sizeof(int) + Marshal.SystemDefaultCharSize.在x64上它失败了.

这是非托管C++给出的:

x86
结构尺寸A:5
设备路径偏移A:4
结构尺寸W:6
设备路径偏移W:4

x64
结构尺寸A:8
设备路径偏移A:4
结构尺寸W:8
设备路径偏移W:4

我想每一个可能的组合StructLayoutMarshalAs参数,但我不能让它返回上述值.

什么是正确的声明?

c# pinvoke winapi memory-alignment

9
推荐指数
1
解决办法
2817
查看次数

C(++)struct强制额外填充

我已经看到了无数问题的形式"我不喜欢填充如何关闭它",但还没有找到任何关于强制编译器提供额外填充的内容.

我的具体情况看起来像

struct particle{
  vect2 s;
  vect2 v;
  int rX;
  int rY;
  double mass;
  int boxNum;
};
Run Code Online (Sandbox Code Playgroud)

哪里vect2很简单struct {double x; double y;} vect2.为了使用SSE2,我需要能够加载一对双精度数,对齐到16字节边界.这曾经工作,直到我添加额外的int,将我的结构大小从48字节推到56字节.结果是段错误.

是否有某种编译器指令我可以使用"填充此结构使其成为16字节长的倍数",或"此结构具有16字节的对齐"?我知道我可以手动完成(例如,添加一个额外的字符[12]),但我真的只是告诉编译器(GCC,最好是ICC兼容),如果我改变它,就不必手动完成结构在未来.

c c++ gcc struct memory-alignment

9
推荐指数
3
解决办法
6114
查看次数

分配初始化的对齐内存

我正在编写一个程序(在C++中),我需要在其中分配其起始地址应与缓存行大小对齐的数组.当我分配这些数组时,我也希望将内存初始化为零.

现在我使用posix_memalign函数工作了.这适用于获取内存对齐的数组,但数组未经过限制.有什么更好的函数可以用来在我初始化它们时将数组清零,或者我是否只需要为我编写一个单独的循环来解决它?

c c++ posix memory-alignment dynamic-allocation

9
推荐指数
1
解决办法
1821
查看次数

为什么此代码与MSVC无效对齐?

我已经在ideone.com上测试了这个代码并且16它应该输出.但是,当我在Visual Studio 2013中尝试它时,它显示8.它是编译器的错误还是缺少C++ 11支持?

#include <iostream>
#include <type_traits>
using namespace std;
using float_pack = aligned_storage<4 * sizeof(float), 16>::type;
int main() {

    cout << alignment_of<float_pack>::value << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用了alignment_of,因为MSVC不支持alignof.

编辑:我看到我无法16与之对齐aligned_storage.但为什么这个片段没问题呢?

#include <iostream>
#include <type_traits>
#include <xmmintrin.h>
using namespace std;

__declspec(align(16)) struct float_pack {
    float x[4];
};

int main()
{
    cout << alignment_of<float_pack>::value << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是16.这是否意味着编译器在使用扩展时可以提供更大的对齐?为什么我不能达到同样的效果aligned_storage?只是因为MSVC没有提供那个aligned_storage

c++ memory-alignment visual-c++ c++11

9
推荐指数
1
解决办法
1437
查看次数

为什么对齐是2的幂?

cppreference有一个引用:

每个对象类型都有称为对齐要求的属性,它是一个整数值(类型为std :: size_t,总是2的幂),表示可以分配此类对象的连续地址之间的字节数.

据我所知,这个参考文献是非规范性的.但是alignof(T)标准中没有关于价值的东西,而不是它alignof(std::max_align_t).

显然,对齐是2的幂.为什么对齐不是3?

c++ memory-alignment

9
推荐指数
1
解决办法
1990
查看次数

使用指针打包结构成员时的编译器警告

许多C / C ++编译器(包括gcc和clang)都具有称为打包结构的功能。由于许多原因,它派上用场,但必须谨慎使用。一个潜在的陷阱是,您将指向结构成员的指针用作另一个函数的参数。现在,该函数不知道未对齐的指针。让我用一些代码说明一下我的意思:

#pragma pack(1)
typedef struct { int x; } uas;
#pragma pack()

void foo(int *f) {
  // some code using the value of *f
}
void bar(uas *b) {
  foo(&(b->x));
}
Run Code Online (Sandbox Code Playgroud)

int在32位计算机上的对齐方式通常为4。foo()如果f没有4字节对齐,则编译器现在可能会为此生成代码。在较旧的ARM体系结构中就是这种情况。

现在struct uas和其中的所有成员都具有1的对齐保证。显然,传递b->xto 的地址foo()是一个坏主意。

GCC和clang具有编译器警告(-Wcast-align),例如,通过将其转换char*为来触发该警告int*。使用指向压缩结构成员的指针,即使两者都支持,似乎也不会触发此警告。我也试过-Wall-Wextra,但他们甚至不包括-Wcast-align

我的主要问题是GCC,clang或任何其他支持打包结构的编译器是否有警告,该警告将由上述特定示例触发。看起来,如果编译器支持压缩结构,则必须发出这样的警告。

c c++ struct pointers memory-alignment

9
推荐指数
1
解决办法
4576
查看次数

C ++内存对齐-我们应该注意吗?

考虑在具有以下类型对齐方式的x64位Windows操作系统上工作:

C ++在我的PC上建立类型对齐

据我了解,做这样的事情非常不好:

struct X_chaotic
{
    bool flag1;
    double d1;
    bool flag2;
    double d2;
    bool flag3;
    double d3;
    //... and so on ...
};
Run Code Online (Sandbox Code Playgroud)

根据C ++对齐,缓存行和最佳实践 以及数据结构对齐,编写此代码应该更好/更快并且更紧凑:

struct X_alignOrder
{
    double d1;
    double d2;
    double d3;
    //... all other doubles ...
    bool flag1;
    bool flag2;
    bool flag3;
    //... all other bools ...
};
Run Code Online (Sandbox Code Playgroud)

成员以比对大小的顺序声明,从最高比对开始。

可以肯定地说按对齐大小对数据成员的声明进行排序是个好主意吗?您会说这是最佳做法吗?还是没有区别?

(由于C ++标准,我听说编译器无法重新排列定义的顺序,这甚至适用于在类的访问说明符块中声明的所有数据成员)

因为我从没读过这本书,所以无论是在Scott Meyers的书还是Bjarne Stroustrup的书中,我都不知道应该为我的日常工作重新排列数据声明的顺序。

c++ memory-alignment

9
推荐指数
1
解决办法
153
查看次数