Escrevi um exemplo muito simples que demonstra o alinhamento de endereços de um arquivo struct
.
#include <iostream>
struct Silly {
char a;
char b;
char c;
};
int main() {
std::cout << "sizeof(Silly): " << sizeof(Silly) << std::endl;
std::cout << "alignof(Silly): " << alignof(Silly) << std::endl;
auto p_silly = new Silly[2];
std::cout << "address[0]: " << &p_silly[0] << std::endl;
std::cout << "address[1]: " << &p_silly[1] << std::endl;
std::cout << "stride: " << &p_silly[1] - &p_silly[0] << std::endl;
delete[] p_silly;
}
Compilando isso com g++ -std=c++23
, encontro os seguintes resultados:
sizeof(Silly): 3
alignof(Silly): 1
address[0]: 0x63b1ada176c0
address[1]: 0x63b1ada176c3
stride: 1
Essa saída não faz sentido para mim.
sizeof() = 3
é sensato, já que a struct contém 3 bytes de dados. Não há preenchimento, já que cada campo é um char
, os processadores podem carregar e armazenar bytes únicos de qualquer endereço.
alignof() = 1
não faz sentido para mim. O alinhamento é o número de bytes entre endereços sucessivos onde um objeto pode ser alocado. Eu esperaria ver um valor de 3
aqui?
Os dois endereços mostram que dois struct Silly
foram alocados um ao lado do outro, sem preenchimento. O endereço do segundo objeto está 3 bytes mais adiante do que o primeiro. Isso faz sentido.
stride
inicialmente me confundiu, mas percebi que esse é o número de elementos entre os dois endereços. Inicialmente pensei que deveria ser o número de bytes entre os dois endereços.
Por que é alignof
igual a 1
?
Alinhamento não é o que você pensa que é. Não é o número de bytes entre localizações onde dois objetos de um tipo podem coexistir . É o número de bytes entre endereços válidos onde um objeto de um tipo pode ser alocado.
Não importa que tentar colocar duas instâncias de
Silly
em endereços alinhados consecutivos possa se sobrepor.