アラインメントを理解するのであれば、一度は複数のアラインメント値でメモリー割り当てをしてみることだと思います。
筆者も実際にプログラムを動かしたアラインメントを分析するだけで、理解が深まったと感じますし、確信が持てない時は実際にコードしてみるのが一番です。
main.c.
1 #include <stdlib.h> 2 #include <stdio.h> 3 4 int main() 5 { 6 int *ptr[5]; 7 int i,alignment,ret; 8 for(alignment = 8; alignment < 512; alignment <<= 1) { 9 for(i = 0; i < 5; i++) 10 { 11 ret = posix_memalign((void**)(&ptr[i]),alignment,sizeof(int)); 12 if(ret != 0){ 13 perror("posix_memalign"); 14 exit(1); 15 } 16 printf("%d: 0x%lx\n",alignment,(unsigned long)(ptr[i])); 17 } 18 19 for(i = 0; i < 5; i++) 20 { 21 free(ptr[i]); 22 } 23 printf("========\n"); 24 } 25 }
ビルドと実行結果.
$ gcc main.c $ ./a.out 8: 0x56283798d260 8: 0x56283798d690 8: 0x56283798d6b0 8: 0x56283798d6d0 8: 0x56283798d6f0 ======== 16: 0x56283798d6f0 16: 0x56283798d6d0 16: 0x56283798d6b0 16: 0x56283798d690 16: 0x56283798d260 ======== 32: 0x56283798d740 32: 0x56283798d780 32: 0x56283798d820 32: 0x56283798d860 32: 0x56283798d900 ======== 64: 0x56283798d940 64: 0x56283798da00 64: 0x56283798da80 64: 0x56283798db40 64: 0x56283798db80 ======== 128: 0x56283798dc80 128: 0x56283798dd00 128: 0x56283798de00 128: 0x56283798de80 128: 0x56283798df80 ======== 256: 0x56283798e100 256: 0x56283798e200 256: 0x56283798e300 256: 0x56283798e500 256: 0x56283798e600 ========
このサンプルでは 5 回のループをするための配列 ptr とアラインメント変数 alignment を宣言しておきます。
6 int *ptr[5]; 7 int i,alignment,ret;
各ループで alignment を 2 乗にアプデートしていきます。
8 for(alignment = 8; alignment < 512; alignment <<= 1) { 9 for(i = 0; i < 5; i++) 10 {
これによって 5 個のアラインメントのパターンをテストします。
メモリー割り当ての行は以下の箇所です。
11 ret = posix_memalign((void**)(&ptr[i]),alignment,sizeof(int));
この場合は ptr の指す int 型のサイズをベースに、色々なアラインメントをテストしています。
例えば以下のアラインメントは 256 バイトです。
256: 0x56283798e100 256: 0x56283798e200 256: 0x56283798e300 256: 0x56283798e500 256: 0x56283798e600
下 2 桁が 0 なので正しいアドレスにアラインされてますね。
Copyright 2018-2019, by Masaki Komatsu