- ベストアンサー
2次元配列を動的に確保する方法
- 2次元配列を動的に確保する方法について質問があります。
- ネットで見つけたコードでは、データの領域を全部確保してからポインタを割り当てる方法が使われています。
- この方法は一般的であり、一度に確保することで連続領域に割り当てられる利点があると思われます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
私は上の方を使用しています。 その理由は、hが100だったとして、iが30の時にヒープが足りなくなってしまった場合に、エラー処理として既に確保済の30個はfreeで開放しなければなりませんが、上の方であれば、一回のmallocで100個分の全体が確保できるかできないかのどちらかです。従って既に確保済の部分だけを開放するという細かい操作が必要なくなります。
その他の回答 (5)
- Tacosan
- ベストアンサー率23% (3656/15482)
「2次元配列に値を代入するまでちょっと時間差があるので初期化されてた方が安心かな」ということだけど, もし本当にそんなことを言うようなら書き直しをさせそうな気がする. そもそも「時間差」なんて関係ないよね. ちなみに, どのような値で「初期化」されるかわかっていますか? その値は適切ですか? あと, 規格に従う限り sizeof(char) は必ず 1 です>#5. ただし, ぎりぎりいうと「アライメントをあわせるのにビットアンドを使うのが妥当か」というと困る. アライメントまわりは「一昔前の 32ビットアドレスの RISC」なら (ほぼ) 必ず言及されることだったりするんで, どうしても気になっちゃうんだよね....
- wormhole
- ベストアンサー率28% (1626/5665)
Itaniumの32ビットモードだとアライメントの問題起こすのは確かです。>#2 アライメントを考慮するなら size_t siz = (sizeof(double *) * h + sizeof(double) - 1) & ~(sizeof(double) - 1); w = (double **)malloc(siz + sizeof(double) * v * h); w[0] = (double *)(((char *)w) + siz); for (int i = 1; i < h; i++) { w[i] = w[i - 1] + v; } になるのかなぁ。 sizeof(char)==1を期待してるのは、それはそれで問題なんだろうけど。
- Tacosan
- ベストアンサー率23% (3656/15482)
#1 の方法だと ・double * は 4バイトかつ 4バイトアライン ・double は 8バイトかつ 8バイトアライン という環境でかつ h が奇数のときに死にます. 今どきそんな環境があるかどうかは知りません (し将来的にそれに類似する環境が発生するかどうかもわかりません) が, かつてあったことも事実. あと, calloc を使うことによる「安心感」がどのようなものか, 説明できますか? 説明できるなら calloc でも malloc でも好きな方を使えばいいですが, もし説明できないとしたら危ないかもしれませんよ.
お礼
なるほど... 正直callocについてはよくわかってないです。ただ2次元配列に値を代入するまで ちょっと時間差があるので初期化されてた方が安心かなとよくわかってないながら思っただけです。 どう危ないか教えて頂けるとありがたいです。
- Tacosan
- ベストアンサー率23% (3656/15482)
厳密にいうとそれはアライメントの問題を起こす余地があるような気がします>#1. ところで, なんで calloc 使ってるの?
お礼
あんまり良くないということですか? callocは特に意味はなかったです。なんとなく安心感があって使ってました。 mallocの方が良いですか?
- wormhole
- ベストアンサー率28% (1626/5665)
>それと何かメリットはあるんでしょうか? malloc()といえど何らかの処理コストがありますし呼び出し回数が少ない方が処理時間は少なくなります(体感はできないでしょうけど)。 またヒープの管理領域分の節約にもなります。 でも更に突き詰めるなら w = (double **)malloc(sizeof(double *) * h + sizeof(double) * v * h); w[0] = (double *)(w + h); for (int i = 1; i < h; i++) { w[i] = w[i - 1] + v; } じゃないかなぁ。
お礼
回答ありがとうございます。 勉強になります。
お礼
回答ありがとうございます。 確かにそういうケースも考えられますね。とてもわかりやすいです。