構造体とメモリについて質問です
構造体とメモリについて質問です
構造体とメモリについて質問です.
プログラム
#include <stdio.h>
int main(void)
{
struct A{
int a;
double b;
char c,d;
}test;
printf("&test.a = %p \n", &test.a);
printf("&test.b = %p \n", &test.b);
printf("&test.c = %p \n", &test.c);
printf("&test.d = %p \n", &test.d);
return 0;
}
実行結果
&test.a = 0x7ffe805ec0c0
&test.b = 0x7ffe805ec0c8
&test.c = 0x7ffe805ec0d0
&test.d = 0x7ffe805ec0d1
質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
ちなみに以下のメモリ増加は正常に行われています.
b→c : +8bite
c→d : +1bite
プログラム
#include <stdio.h>
int main(void)
{
struct A{
int a;
double b;
char c,d;
}test;
printf("&test.a = %p \n", &test.a);
printf("&test.b = %p \n", &test.b);
printf("&test.c = %p \n", &test.c);
printf("&test.d = %p \n", &test.d);
return 0;
}
実行結果
&test.a = 0x7ffe805ec0c0
&test.b = 0x7ffe805ec0c8
&test.c = 0x7ffe805ec0d0
&test.d = 0x7ffe805ec0d1
質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
ちなみに以下のメモリ増加は正常に行われています.
b→c : +8bite
c→d : +1bite
Re: 構造体とメモリについて質問です
これは構造体のメモリ上のアライメントという非常に処理系依存のお話です。
https://www.mm2d.net/main/legacy/c/c-15.html
https://wpedia.goo.ne.jp/wiki/%E3%83%87 ... 3%E3%83%88
https://qiita.com/hoboaki/items/46700f03b522193e9747
つまり この int は8 バイトアライメント(= 64ビットアライメント)です。
https://www.mm2d.net/main/legacy/c/c-15.html
https://wpedia.goo.ne.jp/wiki/%E3%83%87 ... 3%E3%83%88
https://qiita.com/hoboaki/items/46700f03b522193e9747
つまり この int は8 バイトアライメント(= 64ビットアライメント)です。
Re: 構造体とメモリについて質問です
intではなくdoubleですね。Math さんが書きました: ↑4年前つまり この int は8 バイトアライメント(= 64ビットアライメント)です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 構造体とメモリについて質問です
>intではなくdoubleですね。
違うよ
#1
>質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
このint ですよ。
違うよ
#1
>質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
このint ですよ。
Re: 構造体とメモリについて質問です
バイトは、bite ではなく、byte です。YUKI007BKB さんが書きました: ↑4年前質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
int型のオブジェクト(変数)のサイズは 4バイトで、メモリ上では
4バイト境界(4の倍数)にしか配置できません。すなわち、
0x7ffe805ec0c0~0x7ffe805ec0c3 のアドレスに配置できますが、
0x7ffe805ec0c1~0x7ffe805ec0c4 のアドレスに配置できまません。
double型のオブジェクト(変数)のサイズは 8バイトで、メモリ上では
8バイト境界にしか配置できません。
test.a の次のアドレスは 0x7ffe805ec0c4 ですが、これは 8バイト
境界ではありません。したがって、次の 8バイト境界である
0x7ffe805ec0c8 から test.b が始まるのです。
0x7ffe805ec0c4~0x7ffe805ec0c7 の 4バイトは、パディング(詰め物)
と呼ばれるもので、これは test.b が double型で 8バイト境界である
ことによりできたものです。
test.a の int型が 8バイト境界になったのではありません。
C の規格書では、alignment という用語を「境界調整」と翻訳しています。
また、「int型のオブジェクト(変数)のサイズは 4バイトで、メモリ上では
4バイト境界(4の倍数)にしか配置できません。」と書きましたが、
CPU によっては、どこからでも配置できるものがあります。
PC でよく使われているインテルの CPU がそうです。ただし、そういうこと
をするとメモリアクセスに時間がかかることになります。
スマートフォンなどに使われている ARM の CPU では不正な境界への
アクセスはできないようです。
Re: 構造体とメモリについて質問です
図を書いてみると分かりやすいでしょう。
メモリ配置は次の通りです。
sizeof(struct A) は 24 です。
次のようなメモリ配置にしたら .b のメモリアクセスが
2回必要になって遅くなります。
わかりましたか?
返信お待ちしております。
メモリ配置は次の通りです。
struct S
+---+---+---+---+---+---+---+---+
| .a (int) | (padding) |
+---+---+---+---+---+---+---+---+
| .b (double) |
+---+---+---+---+---+---+---+---+
|.c |.d | (padding) |
+---+---+---+---+---+---+---+---+
次のようなメモリ配置にしたら .b のメモリアクセスが
2回必要になって遅くなります。
struct S
+---+---+---+---+---+---+---+---+
| .a (int) | .b (double前半)|
+---+---+---+---+---+---+---+---+
| .b (double後半)|.c |.d |
+---+---+---+---+---+---+
返信お待ちしております。
Re: 構造体とメモリについて質問です
dxlib ではポインターのアドレス値が4バイトか8バイトかで32ビットコンピューターか64ビットコンピューターか切り分けています。
64ビットコンピューターの場合はプログラムカウンターをインクリメントしてレジスターに64ビットデータを取り込むため8バイトのデータが必要です。
速度を優先するには半分無駄遣いをするのでしょうね。
64ビットコンピューターの場合はプログラムカウンターをインクリメントしてレジスターに64ビットデータを取り込むため8バイトのデータが必要です。
速度を優先するには半分無駄遣いをするのでしょうね。
Re: 構造体とメモリについて質問です
まず、double型のメンバbが4の倍数であり8の倍数でないアドレス(メンバaの直後)に配置されず、Math さんが書きました: ↑4年前>intではなくdoubleですね。
違うよ
#1
>質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
このint ですよ。
8の倍数であり16の倍数ではないアドレスに配置されていることから、
この環境ではdouble型が8バイトアラインメントであることが読み取れます。
構造体中のdouble型メンバであるbを8バイトアラインメントにするため、
構造体A全体が8バイトアラインメント(もしくは8の倍数アラインメント)になると考えられます。
その結果、構造体Aの先頭にある「この」int型のメンバaは、結果的に8バイトアラインメントになりますね。
この環境で一般のintが何バイトアラインメントかは、提示された情報からは読み取れなそうです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 構造体とメモリについて質問です
返信遅くなってしまい申し訳ありません.
初めてこちらのサイトを利用させていただきましたが,皆さんのおかげで疑問を解消することができました.
構造体がメモリアクセスを考えて余裕をもたせていること,4byte境界,8byte境界という性質があることなど大変勉強になりました.
今後もぜひ利用させていただこうと思いますので,もし見かけたらまたお力添えをよろしくお願いいたします.
ありがとうございました.
by 駆け出しプログラマー(大学4年生)
初めてこちらのサイトを利用させていただきましたが,皆さんのおかげで疑問を解消することができました.
構造体がメモリアクセスを考えて余裕をもたせていること,4byte境界,8byte境界という性質があることなど大変勉強になりました.
今後もぜひ利用させていただこうと思いますので,もし見かけたらまたお力添えをよろしくお願いいたします.
ありがとうございました.
by 駆け出しプログラマー(大学4年生)