
アドレス格納のための二次元配列のメモリ動的確保
二次元配列のためにメモリを動的確保しなければならないのですが、
その配列に格納したいものが
「DATA型のポインタ」です。(DATA型はtypedefした構造体です。)
プログラム実行中にmallocで確保した、数あるDATA型の構造体の、その先頭アドレスを
リストアップするための配列です。
この場合、どのような形でmallocすればよいのでしょうか?
教えていただけるとありがたいです。よろしくお願いいたします。
--
たとえば m×n のint型の配列は、
◆ int *i;
◆ i = (int *)malloc( m * n * sizeof(int) );
となりますよね。
この要領がでやるのが一般的にわかりやすいものだとするならその方法でやりたい
(後発の人が自分のソースコードを読む可能性があるため)のです。
--
同様にm×nの「DATA型のポインタを格納するための二次元配列」を動的確保したい場合、
◆ DATA *d;
◆ d = (DATA *)malloc( m * n * sizeof(DATA) );
この文にどのように付け加えたら良いのでしょう?
もうあと一歩な気がするのですが(笑)。しかし参考書等で勉強しましたがわかりませんでした・・・。
わかる方、どなたかよろしくお願いいたしますm(_ _)m
あとこれだけ通ればコンパイルが通るんです!!!!! たぶん(笑)
No.3ベストアンサー
- 回答日時:
m×n の int の配列を
◆ int *i;
◆ i = (int *)malloc( m * n * sizeof(int) );
とするのが「ふつう」なのかなぁ? メモリを節約したいならともかく, そうでなければ
int **i;
i = malloc(m * sizeof (i[0]));
i[0] = malloc(m*n*sizeof (i[0][0]));
/* 以下 i[1]~i[m-1] に確保した領域を分配する */
の方がいいんじゃないかねぇ. ま, ど~でもいいけど.
さておき, 自分で書いた「int の場合」をよく見てください. ここは「int」と明示してあるけど, もっと一般に「T」という型なら当然
T *array;
array = (T *)malloc(m*n*sizeof (T));
でしょ? この「T」に, 適切なものを入れればいい. そんだけ.
御礼が遅くなり申し訳ありません。
コンパイルが通りました!有難うございました。
この「T」がint でも int* でも int** でも使い方は同じなんですね。
実装してみて理解することができました。
これでプログラム内の動的確保の配列全てに関して、宣言の表記とメモリ確保の方法が統一できました。
ソースコードも非常にすっきりして、心晴れやかです。
重ね重ね感謝いたします。
今回は回答を5件頂きました。Tacosan様の回答をベストアンサーに選ばせて頂きました。
No.5
- 回答日時:
>アドレス格納のための二次元配列
この部分、もし動的確保を使わないとすると、例えば
int *p[m][n]; // pは、int型へのポインタを格納する二次元配列
のようになります。
これに類することを動的確保を使って行ないたいのですか?
だとすると、まず定義すべきは
int ***p;
ですね。
御礼が遅くなり申し訳ありません。
コンパイルが通りました!有難うございました。
じつは勘違いしていて、問題は3次元配列だったのですが、
それでも宣言は
int *p[m][n][o];
が
int ****p;
となる、ということで同じものだったということがわかりました。
非常に勉強になりました。有難うございます。
No.4
- 回答日時:
二次元配列って
a[m][n]
みたいに、添字2つを使うもので、 malloc(m*n*sizeof(T)) は、あくまで「 m*n の1次元配列」だと思うんですけど。
たとえ、それを [i*n+j]と2次元的に使うとしても。
DATA *の一次元配列を動的に用意するなら
・DATA *の容器を用意するのだから、sizeof(DATA *) (あるいはDATA*型で宣言された変数)
・帰ってくるのは DATA *用に確保した領域へのポインタだから、 DATA * にポインタの*を付けた DATA ** 型
御礼が遅くなり申し訳ありません。
コンパイルが通りました!有難うございました。
>>上の段
Cはメモリを確保した際、箱の大きささえ合っていればどうとでも使えてしまうので、本質的には同じだと思いますよ。
その意味で、Cには多次元配列は存在しないという主張もあるくらいです。
>>下の段
わかりやすい解説を有難うございました m(_ _)m
おかげで他の回答者様方々の回答のソースの読み方を理解することができました。
No.2
- 回答日時:
「DATA型のポインタを格納するための二次元配列」であれば
DATA **dp;
dp = (DATA**)malloc(m * n * sizeof(DATA *));
となると思います。
構造体の本体は次のように確保していきます。
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
dp[j * m + i] = (DATA *)malloc(sizeof(DATA));
}
}
御礼が遅くなり申し訳ありません。
コンパイルが通りました!有難うございました。
今回は、最終的には DATA ***d; と宣言する方法を採らせて頂きましたが、
上記のソースの意味も今なら読めます。
ポインタの知識が二次元的になって非常にすっきりした感じです。
有難うございました!!
No.1
- 回答日時:
DATA *d[];
と宣言して
malloc(m*n*sizeof(d[0]))
と領域のサイズを計算します。
sizeof()を使用して領域を計算する時には型ではなくて、代入する変数を使用するのが暗黙のルールです。理由は変数の型を変更した場合に、sizeof()を修正するのを忘れてもコンパイラは何もエラーを出さないので、バグになる可能性を小さくするためです。
この回答への補足
あれ?何を勘違いしていたんでしょう・・・。
すみません。お礼の下のほうは無視してくださいw
というか以下に差し替えてくださいorz
正しい回答を頂いた(むしろ僕の最初の質問の趣旨に合わせていただいた)のに・・・。
ホントにすみません・・・。
--
今回は、最終的には DATA ***d; と宣言する方法を採らせて頂きました。
御礼が遅くなり申し訳ありません。
コンパイルが通りました!有難うございました。
領域サイズ計算は教えていただいたものに全て変更しました。バグの可能性を減らすのは精神衛生上、本当に良い事ですね(笑)。
二次元配列なので、宣言としては
DATA ***d;
あるいは
DATA **d[];
だったようです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列の要素数に変数を入れたい...
-
関数から配列を返すには?
-
C言語において、 配列要素をひ...
-
C言語の課題が出たのですが自力...
-
0 からa-1 までの整数の乱数をn...
-
C言語の平均点の出し方
-
アドレス格納のための二次元配...
-
配列のNULL初期化について
-
配列の逆順コピー
-
int i, int i[1];
-
C言語の2次元配列 容量が大き...
-
define で 配列
-
c言語 配列
-
100の階乗のプログラムって
-
c言語
-
fclose()でセグメンテーション違反
-
C言語についてです 5人のテスト...
-
プログラミングに関する問題が...
-
ポインタを使って構造体の配列...
-
C#で配列が空かを判定するには?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
c言語
-
C#で構造体の配列を持った構造...
-
C言語 ファイルの指定された行...
-
C言語において、 配列要素をひ...
-
C言語の課題が出たのですが自力...
-
C#で配列が空かを判定するには?
-
構造体のextern方法
-
C言語の配列のコピーについて
-
c言語 構造体
-
C言語 数値の連続入力について
-
MFC - ダイアログボックスのPic...
-
C++DLLからC#へのコールバック...
-
配列のアドレス部
-
要素数・要素の値が未定の配列...
-
C言語についてです 5人のテスト...
-
.NET C++で、構造体の配列をnew...
-
2番目の最大値を求める
おすすめ情報