C++ 对齐是如何影响内存布局和新位置的行为的?
我们读了很多关于对齐的内容,以及它的重要性,例如对于放置C++ 对齐是如何影响内存布局和新位置的行为的?,c++,memory-alignment,placement-new,memory-layout,alignas,C++,Memory Alignment,Placement New,Memory Layout,Alignas,我们读了很多关于对齐的内容,以及它的重要性,例如对于放置new用法,但我想知道-它到底是如何改变内存的布局的 显然,如果我们这样做 char buffer[10]; std::cout << sizeof buffer; 根据GCC 8.2,未进行优化,导致以下装配: operator new(unsigned long, void*): push rbp mov rbp, rsp mov QWORD PTR [rbp-8], rdi
new
用法,但我想知道-它到底是如何改变内存的布局的
显然,如果我们这样做
char buffer[10];
std::cout << sizeof buffer;
根据GCC 8.2,未进行优化,导致以下装配:
operator new(unsigned long, void*):
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov QWORD PTR [rbp-16], rsi
mov rax, QWORD PTR [rbp-16]
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-12]
mov rsi, rax
mov edi, 4
call operator new(unsigned long, void*)
mov eax, 0
leave
ret
让我们通过删除alignas(int)
部分来稍微更改代码。现在,生成的部件略有不同:
operator new(unsigned long, void*):
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov QWORD PTR [rbp-16], rsi
mov rax, QWORD PTR [rbp-16]
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-10]
mov rsi, rax
mov edi, 4
call operator new(unsigned long, void*)
mov eax, 0
leave
ret
值得注意的是,它只在lea
指令上有所不同,其中第二个参数是[rbp-10]
,而不是[rbp-12]
,正如我们在alignas(int)
版本中所做的那样
请注意,我通常不理解组装。我不会写汇编,但我能读一些。据我所知,这种差异只是改变了内存地址的偏移量,它将保持我们的位置-new
edint
但它实现了什么?我们为什么需要这个?假设我们有一个缓冲区数组的“通用”表示,如下所示:
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
现在,我假设,在放置-new
ingint
(有或没有对齐)之后,我们将得到如下结果:
[x] [x] [x] [x] [ ] [ ] [ ] [ ] [ ] [ ]
其中,x
表示int
的单个字节(我们假设sizeof(int)==4
)
但我肯定错过了什么。还有更多,我不知道是什么。通过将缓冲区
与int
对齐,我们到底能实现什么?如果我们不将其对齐,会发生什么情况?在某些体系结构上,类型必须对齐才能使操作正常工作。例如,int
的地址可能需要是4的倍数。如果它没有如此对齐,那么对内存中的整数进行操作的CPU指令将无法工作
即使在数据没有很好地对齐时一切都正常工作,对齐对性能仍然很重要,因为它确保整数等不会跨越缓存边界
将char
缓冲区与整数边界对齐时,不会影响新放置的工作方式。它只是确保您可以使用placement new在缓冲区的开头放置一个int
,而不违反任何对齐约束。它通过确保缓冲区的地址是4字节的倍数来实现这一点。当您在同一缓冲区中放置新的char
,然后在“之后”立即放置新的int
。@MooingDuck因此假设我永远不会将我放置的类型混入我的缓冲区(假设我以一种非常简单的方式模仿std::vector
的缓冲区),我可以不用对齐就可以做到这一点?不,对齐仍然是一个问题,只是在混合类型之前很难注意到这个问题。相关,但不完全回答这个问题:
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
[x] [x] [x] [x] [ ] [ ] [ ] [ ] [ ] [ ]