C++ - 对象填充的复杂性
C++ - object padding intricacies
我试图深入了解结构和类填充,所以我设计了一个我认为比我在有关该主题的教程中找到的许多示例更具挑战性的示例。我在使用 g++ 的 x64 机器中编译了它,但没有启用任何代码优化。我的代码如下:
class Example
{
private:
long double foobar; // 10 bytes + 6 padded bytes as double follows
double barfoo; // 8 bytes + 8 padded bytes
static float barbar; // didn't count as it's a static member
float *fooputs; // 8 bytes + 8 padded bytes
int footsa; // 4 bytes, stored in the padded portion of float
char foo; // 1 byte, stored in the padded portion of float
public:
int function1(int foo) { return 1; }
void function2(int bar) { foobar = bar; }
};
int main()
{
std::cout << sizeof(Example) << std::endl; // 48 bytes
return 0;
}
虽然我看到Example
的大小是 48 字节,但我预计它是 37 字节。关于我期望的论证如下:
foobar
需要 10 个字节。如下double
,填充还需要 6 个字节。barfoo
需要 8 个字节,因为它是double
。无需填充,如mod(16,8) == 0
*fooputs
需要 8 个字节,因为它是 x64 体系结构中的指针。无需填充,如mod(24,8) == 0
footsa
需要 4 个字节作为整数,无需填充,如mod(32,4) == 0
foo
需要 1 个字节作为字符。 无需填充。
由于结果与预期不同,我试图通过注释 in 和 out 类成员来了解C++如何评估Example
到 48 字节的大小。因此,除了foobar
的论证之外,我还假设了我为每个成员在内联评论中写的理由。
谁能解释一下我如何将大小评估为 48 字节以及我的理由是否正确?
你忘记了最后的填充。sizeof
返回数组中两个相邻成员之间的字节数。在您的情况下,alignof(long double)
很可能是 16,因此每个Example
实例都需要使用 16 字节对齐的地址。
因此,如果在 16 字节对齐的地址 A 处有Example
的第一个实例,然后成员需要 37 个字节,则下一个Example
实例不能存储在 A + 37 字节处,但需要存储在A+k* 16 处。满足 k * 16>= 37 的最小可能k是 3。这最终为您提供了数组中两个Example
实例之间的字节数 3 * 16 = 48,这正好是sizeof(Example)
.
相关文章:
- 在c++中用vector填充一个简单的动态数组
- 如何使用用户输入在C++中正确填充2D数组
- 如何找到大小'x'数组是否完全填充,在C++?
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 通过for循环使用用户输入填充列表
- 具有未知值时的时间复杂性
- 关联容器的下界复杂性:成员函数与非成员函数
- 使用堆查找第K个最大元素的时间复杂性
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 如何正确填充在堆上分配的二维数组?
- 将数字转换为填充字符串
- 有没有办法在一行中填充矢量图
- 用C++中的数字和条件填充向量
- 用真值填充矢量
- 并行标准::复制复杂性
- 使用结构成员指针在C++中填充结构
- 特定算法的复杂性与 3 for?
- 流填充字符的默认定位
- 使用不同算法的 PKCS1v15 填充进行加密 ++ 签名
- C++ - 对象填充的复杂性