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

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

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: 構造体とメモリについて質問です

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

#13

by YUKI007BKB » 4年前

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

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

#12

by みけCAT » 4年前

Math さんが書きました:
4年前
>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が何バイトアラインメントかは、提示された情報からは読み取れなそうです。

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

#11

by Math » 4年前

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

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

#10

by Math » 4年前

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

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

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

#9

by かずま » 4年前

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

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

コード:

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 |
	+---+---+---+---+---+---+
わかりましたか?
返信お待ちしております。

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

#8

by かずま » 4年前

YUKI007BKB さんが書きました:
4年前
質問は,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: 構造体とメモリについて質問です

#7

by Math » 4年前

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

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

このint ですよ。

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

#6

by みけCAT » 4年前

Math さんが書きました:
4年前
つまり この int は8 バイトアライメント(= 64ビットアライメント)です。
intではなくdoubleですね。

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

#5

by Math » 4年前

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

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

#4

by shio » 4年前

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

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

#3

by Math » 4年前

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

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

#2

by shio » 4年前

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

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

#1

by YUKI007BKB » 4年前

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

プログラム

#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

ページトップ