我最近总是遇到以下问题:
-march=native.Eigen::Quaternionf。在其他情况下,会EIGEN_UNALIGNED_ASSERT触发 ,这会导致此页面,我在代码中随处观察到其内容(据我所知)我想成为一个好公民,所以我尝试在一个最小的示例上重现该问题,并将其发布在 stackoverflow 或相关问题跟踪器中。然而,当我只提取触发问题的位时,我总是无法重现崩溃。我的猜测是,内存是否对齐(并且不需要特别注意)也取决于问题位置之前分配的内容,因此周围的代码有助于触发问题。
问题:我可以使用哪些技术和工具来有效确定 Linux 和/或 macOS 上的 C+14 中内存对齐相关崩溃的根源?
我创建了一个简单的演示来展示未对齐的内存存储/加载在 x86_64 和 ARM64 架构上通常不是原子的。该演示由一个 C++ 程序组成,该程序创建两个线程 \xe2\x80\x94,第一个线程 10 亿次调用名为 的函数store,第二个线程对名为 的函数执行相同的操作load。该程序的源代码在这里:
#include <cstdint>\n#include <cstdlib>\n#include <iostream>\n#include <thread>\n\nextern "C" void store(void*);\nextern "C" uint16_t load(void*);\n\nalignas(64) char buf[65];\nchar* ptr;\n\nstatic long n = 1\'000\'000\'000L;\n\nvoid f1()\n{\n for (long i = 0; i < n; i++)\n store(ptr);\n}\n\nvoid f2()\n{\n long v0x0000 = 0;\n long v0x0101 = 0;\n long v0x0100 = 0;\n long v0x0001 = 0;\n long other = 0;\n\n for (long i = 0; i < n; i++)\n {\n uint16_t …Run Code Online (Sandbox Code Playgroud) 我需要一种可移植的方法来确定结构的对齐要求,其中可移植性包括 GCC 的旧版本。部分项目受困于仅支持 C++11 之前标准的嵌入式平台,最早是 GCC v.3.6。
我可以使用一个非 ISO __alignof__(宏?函数?)的 C++11 运算符模拟alignof,但支持它的 GCC 编译器的最早版本是什么?命名方面是否有替代方案或更改?
我已经使用 C 指针有一段时间了,一切都按预期工作。然而现在我遇到了 ISO 标准,该标准规定“如果生成的指针未针对指向的类型正确对齐,则行为未定义”。
这让我不禁要问自己:
这是什么意思?
我们如何安全地将指针转换为其他类型?
我发现这个 C 代码示例据说是不正确的,因为它与更严格对齐的指针类型有关:
int main() {
char c = 'x';
int *ip = (int *)&c;
char *cp = (char *)ip;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我已经理解为什么内存应该根据总线的数据宽度与4字节和8字节对齐.但以下声明让我感到困惑
"IoDrive要求使用O_DIRECT在设备上执行的所有I/O必须是512字节的对齐,并且大小为512字节的倍数."
将地址对齐到512字节的需要是什么.
您可以分配一个std :: vector,它通过定义您自己的分配器来分配对齐的堆内存.您可以使用declspec align在堆栈上分配c样式数组.但是你可以声明一个tr1 :: array来保证索引为零的元素会对齐吗?
在调试问题时,出现以下问题。(请忽略较小的代码错误;该代码仅供参考。)
定义了以下结构:
typedef struct box_t {
uint32_t x;
uint16_t y;
} box_t;
Run Code Online (Sandbox Code Playgroud)
这个结构的实例通过值在函数之间传递(显然是简化的):
void fun_a(box_t b)
{
... use b ...
}
void fun_b(box_t bb)
{
// pass bb by value
int err = funa(bb);
}
void fun_c(void)
{
box_t real_b;
box_t some_b[10];
...
... use real_b and some_b[] ...
...
funb(real_b);
funb(some_b[3]);
...
box_t copy_b = some_b[5];
...
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,像这样比较box_t的两个实例:
memcmp(bm, bn, sizeof(box_t));
Run Code Online (Sandbox Code Playgroud)
在几个嵌套的调用中,使用类似以下的方法来转储box_t arg的字节:
char *p = (char*) &a_box_t_arg;
for (i=0; i < sizeof(box_t); i++) {
printf(" %02X", …Run Code Online (Sandbox Code Playgroud) 对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数.
这个概念有点不清楚.例如:
struct B { long double d; };
struct D : virtual B { char c; }
Run Code Online (Sandbox Code Playgroud)
当D是完整对象的类型时,它将具有类型B的子对象,因此它必须适当地对齐a
long double.
这是什么意思?sizeof(long double)是那种情况之间的字节数?
我正在学习C.在C Primer Plus中,我看到了一个字段示例如下:
struct box_props {
bool opaque : 1;
unsigned int fill_color : 3;
unsigned int : 4;
bool show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned int : 2;
};
Run Code Online (Sandbox Code Playgroud)
我知道中间的4位未命名位字段用于让以下位从一个新字节开始.但是,我不明白为什么在结构的末尾有另一个未命名的位字段.它的目的是什么?有必要吗?
我有一个严格对齐要求的类型(由于使用了AVX操作),它大于平台默认对齐.
为了使这个类的使用更简单,我想专门std::make_shared总是为这种类型使用合适的分配器.
像这样的东西:
namespace std{
template<class... Args> inline
auto make_shared<X, Args...>(Args&&... args){
return std::allocate_shared(allocator_type<X, 32>, std::forward<Args>(args)...);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,标准是否允许这样做?它会按预期工作吗?