未对齐的内存访问:是否定义了行为?

时间:2016-10-07 03:34:25

标签: c++ c++11 memory-leaks memory-alignment memory-access

请考虑以下代码:

#include <iostream>

int main()
{
    char* c = new char('a');
    char ac[4] = {'a', 'b', 'c', 'd'};
    unsigned long long int* u = reinterpret_cast<unsigned long long int*>(c);
    unsigned long long int* uc = reinterpret_cast<unsigned long long int*>(&ac[3]);
    *u = 42;
    *uc = 42;
    std::cout<<*u<<" "<<*uc<<std::endl;
}

这被视为有效代码,还是内存泄漏/未定义行为? 我问,因为通过:

*u = 42;
*uc = 42;

我们正在访问程序无法访问的字节(我猜)。

1 个答案:

答案 0 :(得分:7)

*u = 42;违反严格别名规则会导致未定义的行为。 *uunsigned long long类型的左值,严格别名规则表明这只能用于访问对象(已存在)且类型为long longunsigned long long 。但是,您的代码使用它来访问char

的数组

C ++没有针对对齐访问的特定规则(与C不同)。这是因为在C ++中,由于以下原因之一,编写执行未对齐访问而不会导致未定义行为的代码是不可能的:

  • 违反严格的别名规则。
  • 访问没有对象存在的内存。
  • 向placement-new提供未对齐的地址。