- C++相談室 part140
722 :デフォルトの名無しさん[sage]:2019/02/12(火) 10:06:17.35 ID:dWGWBM0h - >>719
malloc() の戻り値は「void *」で、C だとどんな型のポインタ変数に代入しても エラーや警告が出なかったが、C++ だとエラーが出る。 C++ は型を非常に大切にしていて、 TYPE *ptr = new TYPE; や TYPE *ptr = new TYPE[N]; のように書くのが標準。理由は、必ずコンストラクタを呼ぶようにするためと、 型の異なるポインタには cast しない限りは絶対に代入できないようにするため だと思われる。というのは、delete ptr とした場合に、ptr の型によってどの class の デストラクタが呼ばれるかが変わったり、ptr->func() とした場合に、func が、 どの class のメンバ関数であるかをコンパイラが知るため。わずかでも違っていれば 結果が変わってきてしまう。これが C++ が大きなプログラム開発に向いている 所以でもあって、わずかな間違いでもコンパイラが見つけてくれる確率が高くなっている。 C++ で malloc() をエラーを起こさずに使うには、コンストラクタが(絶対に)存在しない ところのBYTE 配列の場合ですら、 BYTE *ptr = (BYTE *)malloc(N); のように書かなくてははならない。 これは面倒なので(←嘘です)、 BYTE *ptr = new BYTE[N]; と書く習慣になっている。
|
- C++相談室 part140
732 :デフォルトの名無しさん[sage]:2019/02/12(火) 15:08:09.96 ID:dWGWBM0h - >>730
ヘッダ部分を除いたデータ部分としては完全に同じといっても過言ではないんだけど、 ptr = new TYPE; とした場合は、C++ の仕様上は メモリブロックの先頭に「配列の場合には埋め込まれるところの要素数」をコンパイラは 必ずしも埋め込まなくても良いという事になっていて、その場合、delete 命令から見ると、 要素数1の配列とは同じではない。ただし、VC++ の場合には、危険を避けるため、 delete と delete [] は、どちらを書いても問題なく動作するようになっている という文書を読んだ事が有る。 (C++元々の)仕様は、なるべくメモリ使用量も検査量も少なくして効率を上げる、 という哲学から来るものなんだけど、型検査をがちがちにして安全性を高めている一方で、 非常に危険な仕様になっていると言えなくもない。ただし、TYPE が小さなオブジェクトの 場合、new TYPE において、メモリブロックのヘッダ部分を配列と同じ構造にしてしまうの は、結構、メモリの無駄使いにはなる。ただし、それもC#なんかの無駄と比べれば すずめの涙程度の全然問題ない程度のものではある。しかし、それだけ、C++が効率が 良いはずではある。
|
- C++相談室 part140
734 :デフォルトの名無しさん[sage]:2019/02/12(火) 15:22:00.28 ID:dWGWBM0h - >>733
要素数が正確にわからないと、デストラクタを呼び出す回数が分からない。
|
- C++相談室 part140
736 :デフォルトの名無しさん[sage]:2019/02/12(火) 15:44:00.70 ID:dWGWBM0h - >>735
生のメモリブロックも、大きさは管理されているといえばされているんだけど、 理由は分からないけど、サイズを取得するための _msize(ptr) が存在しない ライブラリがある。あと、TYPE が小さい場合、アラインの問題もあって、 MBのサイズがTYPE が2個以上入ってしまうようになってしまう場合も有り得て、 要素数を計算する再にその場合の処理を適切にしないといけない。 恐らく出来ないわけではないはずなんだけど、そういう変な事情も 考慮して元祖の C++ は設計されたんじゃないかな。
|