回答編集履歴

1

図を3つ追加。

2022/05/16 06:23

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -28,3 +28,20 @@
28
28
  ```
29
29
  `` int (*p)[18]; `` は、本来的には `` int arr[18]; `` のような**要素数18の配列をひとまとまりとして指すポインタ**ですが、このポインタがあればN*18の二次元配列を指すことができ、普通の配列のようにアクセスできます。固定した 2003 * 18 というサイズが分かってるのだから、その分のメモリで十分でしょう。
30
30
  二次元配列を使う時、ポインタ配列は必須ではありません。64bit環境で2003個もポインタ並べたら 8 * 2003 = 16024 byte だから16KBもメモリ使っちゃいますよ(貧乏性?w)。
31
+
32
+ ---
33
+ 3つのやり方で、それぞれどのようなメモリ配置になるのか描いてみました。
34
+ 64bit機のCコンパイラは大抵 sizeof int == 4, sizeof(int*) == 8 です。この前提で取得したメモリサイスを計算しました。
35
+
36
+ (1) 2003本のポインタが並ぶ配列と、要素数18のint型配列が2003個。
37
+ (8 * 2003) + (4 * 18 * 2003) = 16024 + 144216 = 160240 bytes ≒ 160KB
38
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-16/ad57be16-ca86-46da-a4fb-85cbc005125f.jpeg)
39
+
40
+ (2) 18本のポインタが並ぶ配列と、要素数2003のint型配列が18個。
41
+ (8 * 18) + (4 * 2003 * 18) = 144 + 144216 = 144360 bytes ≒ 144KB
42
+ 上に比べればポインタ配列のサイズがぐっと小さくなったので許せる範囲かもしれません。注意深く書き換えれば動作するでしょう。しかし書き換えとは、当初 p[x][y] と書いたものを p[y][x] と書き直すことです。とてもお勧めできません。
43
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-16/45ea7274-291d-411e-b1b1-327ad5acb1f2.jpeg)
44
+
45
+ (3) 要素数 18 * 2003 のメモリを取得する。
46
+ 4 * 18 * 2003 = 144216 bytes ≒ 144KB
47
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-16/ced65f9f-d45b-43e8-be36-75d869413567.jpeg)