声明,操作和访问C ++中未对齐的内存 [英] Declare, manipulate and access unaligned memory in C++

查看:88
本文介绍了声明,操作和访问C ++中未对齐的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发布了一个有关未对齐的内存访问的问题,但是给出了答案,我有点迷失了.我经常听到对齐内存访问比未对齐访问有效得多",但实际上我不确定什么是未对齐内存.因此:

I recently posted a question about unaligned memory access, but given the answer, I am a little lost. I often hear that "aligned memory access is far more efficient than unaligned access", but I am actually not sure what is unaligned memory. Consequently:

  • 什么是未对齐内存?
  • 如何声明C ++中未对齐的内容? (小型示例程序)
  • 如何访问和处理C ++中未对齐的内容? (小型示例程序)
  • 是否有一种方法可以使用已定义的行为方法来处理未对齐的内存,或者所有这些都是C ++中平台相关/未定义的行为?

推荐答案

某些内容是否未对齐取决于数据类型及其大小,如Gregg的答案所述.

Whether something is unaligned or not depends on the data type and its size As the answer from Gregg explains.

一个精心编写的程序通常不具有未对齐的内存访问权限,除非编译器引入了该访问权限. (是的,在矢量化过程中会发生,但是我们跳过它).

A well-written program usually does not have unaligned memory access, except when the compiler introduces it. (Yes, that happens during vectorization but let's skip that).

但是您可以用C ++编写程序来强制进行未对齐的内存访问.下面的代码就是这样做的.

But you can write program in C++ to force unaligned memory access. The code below does just that.

#include <iostream>
using namespace std;
int main() {

  int a[3] {1, 2, 3};

  cout << *((long long *)(&a[0])) << endl;
  cout << *((long long *)(&a[1])) << endl;

  cout <<  (long long) (&a[0]) << endl;
  cout << (long long) (&a[1]) << endl;

  return 0;

}

代码的输出是这个

8589934593
12884901890
70367819479584
70367819479588

此程序做什么? 我声明了一个大小为3的整数数组.该数组将对齐4个字节,因为int是4字节的数据类型(至少在我的平台上).因此,a [0]的地址可被4整除.现在,a [0]和a [1]的地址都可被4整除,但只有其中一个的地址可被8整除.

What this program does? I declare an integer array of size 3. This array will be 4 byte aligned because int is a 4 byte data type (at least on my platform). So the address of a[0] is divisible by 4. Now address of both of a[0] and a[1] is divisible by 4 but only address of one of them is divisible by 8.

因此,如果我将a [0]和a [1]的地址强制转换为long long指针(在我的平台上为8字节数据类型),然后将这两个指针作为参考,则其中之一将是未对齐的内存访问.这不是未定义的行为AFAIK,但是它将比对齐的内存访问慢.

So if I cast the address of a[0] and a[1] to a pointer to long long (which is an 8 byte data type on my platform) and then deference these two pointers, one of them will be an unaligned memory access. This is not undefined behavior AFAIK, but it is going to be slower than aligned memory access.

如您所见,此代码包含C样式强制转换,这不是一个好习惯.但是我认为可以强制执行一些奇怪的行为.

As you see this code contains C style casts which is not a good practice. But I think for enforcing some strange behavior that is fine.

如果您对代码输出有疑问,请告诉我.您应该了解字节序和整数表示,才能理解前两行.第三和第四行是整数数组的前两个元素的地址.那应该更容易理解.

let me know if you have question about the output of the code. You should know about endianness and representation of integers to understand the first two lines. The third and fourth line are address of the first two elements of the integer array. That should be easier to understand.

这篇关于声明,操作和访问C ++中未对齐的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆