gpt4 book ai didi

c++ - 奇怪的数据对齐

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:49 25 4
gpt4 key购买 nike

据我所知,数据对齐是将数据放入内存中的 64 位/32 位 block 中以提高 CPU 性能,我使用的是 64 位 linux 机器,我做了一些测试并得到了一些奇怪的结果(我无法解释行为)。

这是我使用的结构:

  class A {
long l0,l1,l2;
};

class B {
long l0,l1,l2,l3;
};

class C {
long l0,l1,l2,l3,l4;
};

测试:

int main() {
C* newC = new C();
B* newB = new B();
A* newA = new A();
int* i = new int();

std::cout << sizeof(A) << std::endl;
std::cout << sizeof(B) << std::endl;
std::cout << sizeof(C) << std::endl;

std::cout << "C : " << newC << std::endl;
std::cout << "B : " << newB << std::endl;
std::cout << "A : " << newA << std::endl;
std::cout << "i : " << i << std::endl;

delete (i);
delete (newC);
delete (newA);
delete (newB);

return 0;
}

只是将每个对象的 1 个对象放入堆中,我在末尾添加了一个指针以查看 newA 占用的内存

结果是这样的:

24
32
40
C : 0x603010
B : 0x603040
A : 0x603070
i : 0x603090

3*16 bytes newCnewB 之间的地址:C 是 40 字节,已经是 64 位的倍数,为什么那些多了 8 个字节??

3*16 字节 newBnewA ?? B 只有 32 个字节,我预计:A : 0x603060

2*16字节newAi之间的地址 ??

最佳答案

当你在堆上分配时,你不能对地址做出任何明确的陈述。

内存分配函数很有可能维护有关已分配 block 的内联信息,这将影响后续 block 的地址,例如:

+--------+-------------+--------+-------------+
| header | alloced mem | header | alloced mem | ...
+--------+-------------+--------+-------------+

此外,为了提高效率,这些函数可能会将您的内存四舍五入到(例如)八或十六的倍数(您仍然不允许使用它,因为您不知道 关于它)。这可能会进一步影响您看到的分配内存的地址。


可以看到两者这些影响共同反对你的经典案例:

#include <iostream>
#include <cstdlib>
int main (int argc, char *argv[]) {
char *one = new char[std::atoi(argv[1])];
char *two = new char[std::atoi(argv[1])];
std::cout << static_cast<void*>(one) << '\n';
std::cout << static_cast<void*>(two) << '\n';
return 0;
}

和脚本:

#!/usr/bin/bash
for i in {01..37}; do
echo $i $(./qq $i)
done

在我的系统上,输出:

01 0x800102e8 0x800102f8
02 0x800102e8 0x800102f8
:: (all the same address pairs in here and in gaps below)
12 0x800102e8 0x800102f8
13 0x800102e8 0x80010300
::
20 0x800102e8 0x80010300
21 0x800102e8 0x80010308
::
28 0x800102e8 0x80010308
29 0x800102e8 0x80010310
::
36 0x800102e8 0x80010310
37 0x800102e8 0x80010318

当您只分配一个字符时,两者之间的字节数高达 16

保持 16 个字节,一直到 new char[12],并且每次你在之后添加 8 个字符时增加 8 个字节,似乎 指示四字节 header , header +数据最少十六字节,以及 header +数据区域的八字节分辨率。

请记住,这是基于我对这些东西的书写方式的了解,因此,有根据的猜测,仍然是猜测,你应该靠它。它可能会使用与我想象的完全不同的策略,或者它可能会针对更大的 block 改变其策略。

如果您想知道类型真正占用了多少空间,请创建一个包含两个的数组并计算出x[0]x[1]。您会发现它应该与您从 sizeof 获得的相同。

关于c++ - 奇怪的数据对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30209628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com