未对齐的内存访问:是否定义了行为?
Unaligned memory access: is it defined behavior or not?
考虑以下代码:
#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;
}
这是否被视为有效代码,还是内存 leak/undefined 行为?
我问,因为通过:
*u = 42;
*uc = 42;
我们正在访问程序不应访问的字节(我猜)。
*u = 42;
通过违反严格的别名规则导致未定义的行为。 *u
是类型 unsigned long long
的左值,严格的别名规则规定这只能用于访问对象(已经存在)并且类型为 long long
或 unsigned long long
.但是,您的代码使用它来访问 char
.
的数组
C++ 没有针对对齐访问的特定规则(与 C 不同)。这是因为在 C++ 中,不可能编写执行未对齐访问的代码,而不会由于以下原因之一导致未定义的行为:
- 违反了严格的别名规则。
- 正在访问不存在对象的内存。
- 正在向 placement-new 提供未对齐的地址。
考虑以下代码:
#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;
}
这是否被视为有效代码,还是内存 leak/undefined 行为? 我问,因为通过:
*u = 42;
*uc = 42;
我们正在访问程序不应访问的字节(我猜)。
*u = 42;
通过违反严格的别名规则导致未定义的行为。 *u
是类型 unsigned long long
的左值,严格的别名规则规定这只能用于访问对象(已经存在)并且类型为 long long
或 unsigned long long
.但是,您的代码使用它来访问 char
.
C++ 没有针对对齐访问的特定规则(与 C 不同)。这是因为在 C++ 中,不可能编写执行未对齐访问的代码,而不会由于以下原因之一导致未定义的行为:
- 违反了严格的别名规则。
- 正在访问不存在对象的内存。
- 正在向 placement-new 提供未对齐的地址。