構造体とメモリについて質問です

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YUKI007BKB

構造体とメモリについて質問です

#1

投稿記事 by YUKI007BKB » 5ヶ月前

構造体とメモリについて質問です.

プログラム

#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

shio
記事: 8
登録日時: 5ヶ月前

Re: 構造体とメモリについて質問です

#2

投稿記事 by shio » 5ヶ月前

確か構造体は動作を高速化させるために余裕を持たせていると聞いたことがあるような気がします。

Math

Re: 構造体とメモリについて質問です

#3

投稿記事 by Math » 5ヶ月前

これは構造体のメモリ上のアライメントという非常に処理系依存のお話です。

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ビットアライメント)です。

shio
記事: 8
登録日時: 5ヶ月前

Re: 構造体とメモリについて質問です

#4

投稿記事 by shio » 5ヶ月前

質問者じゃないけど勉強になりました。ありがとう。

Math

Re: 構造体とメモリについて質問です

#5

投稿記事 by Math » 5ヶ月前

#2 でshio さんのいわれる通りですね。

アバター
みけCAT
記事: 6235
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 構造体とメモリについて質問です

#6

投稿記事 by みけCAT » 5ヶ月前

Math さんが書きました:
5ヶ月前
つまり この int は8 バイトアライメント(= 64ビットアライメント)です。
intではなくdoubleですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: 構造体とメモリについて質問です

#7

投稿記事 by Math » 5ヶ月前

>intではなくdoubleですね。
違うよ

#1
>質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?

このint ですよ。

かずま

Re: 構造体とメモリについて質問です

#8

投稿記事 by かずま » 5ヶ月前

YUKI007BKB さんが書きました:
5ヶ月前
質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?
バイトは、bite ではなく、byte です。

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: 構造体とメモリについて質問です

#9

投稿記事 by かずま » 5ヶ月前

図を書いてみると分かりやすいでしょう。

メモリ配置は次の通りです。

コード:

struct S
	+---+---+---+---+---+---+---+---+
	|  .a (int)     |   (padding)   |
	+---+---+---+---+---+---+---+---+
	|  .b (double)                  |
	+---+---+---+---+---+---+---+---+
	|.c |.d |      (padding)        |
	+---+---+---+---+---+---+---+---+
sizeof(struct A) は 24 です。

次のようなメモリ配置にしたら .b のメモリアクセスが
2回必要になって遅くなります。

コード:

struct S
	+---+---+---+---+---+---+---+---+
	|  .a (int)     | .b (double前半)|
	+---+---+---+---+---+---+---+---+
	| .b (double後半)|.c |.d |
	+---+---+---+---+---+---+
わかりましたか?
返信お待ちしております。

Math

Re: 構造体とメモリについて質問です

#10

投稿記事 by Math » 5ヶ月前

dxlib ではポインターのアドレス値が4バイトか8バイトかで32ビットコンピューターか64ビットコンピューターか切り分けています。

64ビットコンピューターの場合はプログラムカウンターをインクリメントしてレジスターに64ビットデータを取り込むため8バイトのデータが必要です。
速度を優先するには半分無駄遣いをするのでしょうね。

Math

Re: 構造体とメモリについて質問です

#11

投稿記事 by Math » 5ヶ月前

.Net にはInt64, Int32があるからInt64を使えばいいのだけどね。

アバター
みけCAT
記事: 6235
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 構造体とメモリについて質問です

#12

投稿記事 by みけCAT » 5ヶ月前

Math さんが書きました:
5ヶ月前
>intではなくdoubleですね。
違うよ

#1
>質問は,a はint型で4biteのはずですが,なぜ a→b のときに 8bite進んでいるのでしょうか?

このint ですよ。
まず、double型のメンバbが4の倍数であり8の倍数でないアドレス(メンバaの直後)に配置されず、
8の倍数であり16の倍数ではないアドレスに配置されていることから、
この環境ではdouble型が8バイトアラインメントであることが読み取れます。
構造体中のdouble型メンバであるbを8バイトアラインメントにするため、
構造体A全体が8バイトアラインメント(もしくは8の倍数アラインメント)になると考えられます。
その結果、構造体Aの先頭にある「この」int型のメンバaは、結果的に8バイトアラインメントになりますね。
この環境で一般のintが何バイトアラインメントかは、提示された情報からは読み取れなそうです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YUKI007BKB

Re: 構造体とメモリについて質問です

#13

投稿記事 by YUKI007BKB » 5ヶ月前

返信遅くなってしまい申し訳ありません.
初めてこちらのサイトを利用させていただきましたが,皆さんのおかげで疑問を解消することができました.
構造体がメモリアクセスを考えて余裕をもたせていること,4byte境界,8byte境界という性質があることなど大変勉強になりました.
今後もぜひ利用させていただこうと思いますので,もし見かけたらまたお力添えをよろしくお願いいたします.
ありがとうございました.
by 駆け出しプログラマー(大学4年生)

返信

“C言語何でも質問掲示板” へ戻る