相关疑难解决方法(0)

为什么“对齐”在32位和64位系统上相同?

我想知道编译器是否会在32位和64位系统上使用不同的填充,因此我在一个简单的VS2019 C ++控制台项目中编写了以下代码:

struct Z
{
    char s;
    __int64 i;
};

int main()
{
    std::cout << sizeof(Z) <<"\n"; 
}
Run Code Online (Sandbox Code Playgroud)

我对每个“平台”设置的期望:

x86: 12
X64: 16
Run Code Online (Sandbox Code Playgroud)

实际结果:

x86: 16
X64: 16
Run Code Online (Sandbox Code Playgroud)

由于x86上的存储字大小为4个字节,因此这意味着它必须以i两个不同的字存储字节。所以我认为编译器将以这种方式进行填充:

struct Z
{
    char s;
    char _pad[3];
    __int64 i;
};
Run Code Online (Sandbox Code Playgroud)

所以我可以知道背后的原因是什么?

  1. 是否与64位系统具有前向兼容性?
  2. 由于在32位处理器上支持64位数字的限制?

c++ abi memory-alignment 32bit-64bit visual-c++

16
推荐指数
3
解决办法
2819
查看次数

为什么在AMD64上对mmap内存的未对齐访问有时会出现段错误?

我有这段代码在AMD64兼容CPU上运行Ubuntu 14.04时会出现段错误:

#include <inttypes.h>
#include <stdlib.h>

#include <sys/mman.h>

int main()
{
  uint32_t sum = 0;
  uint8_t *buffer = mmap(NULL, 1<<18, PROT_READ,
                         MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  uint16_t *p = (buffer + 1);
  int i;

  for (i=0;i<14;++i) {
    //printf("%d\n", i);
    sum += p[i];
  }

  return sum;
}
Run Code Online (Sandbox Code Playgroud)

如果使用分配内存,则仅此段错误mmap.如果我使用malloc,堆栈上的缓冲区,或全局变量,它不会段错误.

如果我将循环的迭代次数减少到少于14的次数,则不再是段错误.如果我从循环内打印数组索引,它也不再是段错误.

为什么未对齐的内存访问能够访问未对齐地址的CPU上的段错误,为什么只有在这种特定情况下呢?

c gcc mmap x86-64 auto-vectorization

5
推荐指数
1
解决办法
1608
查看次数