- ベストアンサー
newとmallocによるメモリの動的確保について
- C++でのメモリの動的確保方法には、newとmallocがあります。
- mallocはC言語の標準ライブラリであり、newはC++の演算子です。
- 一般的には、C++ではnewを使用した方が良いとされていますが、mallocの方が速度が速い場合もあります。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
まあ, operator new[] は operator delete[] のための管理情報を追加しなきゃならないのでどうしても malloc より遅くなる (少なくとも「速くなることだけはない」) んですけどね.... どうしても速度が欲しいなら malloc, お手軽を求めるなら std::vector を使うのが普通かな. ああ, 今どき 3.4.5 もどうかと思うので 4.3.3 なり 4.4.2 にするってのも考えるべきかと.
その他の回答 (8)
- jacta
- ベストアンサー率26% (845/3158)
> ごめんなさい、理解できません。 > arrayの要素数は静的に決まるかと。 私自身、少し混乱があったようです。 何を考えていたかというと... 配列を動的に割り付けたい動機というのは、サイズを可変にしたいか、記憶域期間の問題をクリアしたいか、どのどちらかのケースが多いと思います。 そこで、後者の場合であれば、 array<array<char, 256>, 10>* data = new array<array<char, 256>, 10>; で済むのではないかと考えていました。 ただ、最初の話の流れでは、 vector<vector<char> > data; とすることを(私自身)想定していましたので、一貫性を失っていますね。 もちろん、vectorを使った場合でも、記憶域期間の問題をクリアするには、 vector<vector<char> >* data = new vector<vector<char> >; とすることになるのでしょうが。
お礼
実は記憶域期間の問題も抱えていて、別の形で質問させて頂こうと思っています。 STL等が十分に使える環境では、積極的にvectorを使ったほうが良さそうですね。 コメント頂いたキーワードから、知識の幅が広がりました。みなさん、ご回答ありがとうございました。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 単に動的に割り付けたいだけなら、十分かと思います。 ごめんなさい、理解できません。 arrayの要素数は静的に決まるかと。
- jacta
- ベストアンサー率26% (845/3158)
> arrayは固定長なのでmalloc/newの代わりにはなりません。 可変サイズにするならそうですね。 単に動的に割り付けたいだけなら、十分かと思います。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> std::tr1::arrayでもよいと思います。 arrayは固定長なのでmalloc/newの代わりにはなりません。
- jacta
- ベストアンサー率26% (845/3158)
freeとdeleteを間違うようなプログラマは、(もっと紛らわしい)deleteとdelete[]を確実に使い分けられるとは思えません。 理想をいえば、そんなプログラマを使わないのが一番ですが、そうもいかないのであれば、配列形式のnewは全廃したほうがよいでしょう。 代わりはstd::vectorが最有力ですが、TR1が使える環境であれば、std::tr1::arrayでもよいと思います。std::vectorやstd::dequeを使う場合、push_backやinsert後に反復子が無効になるので、フールプルーフを考えると、std::tr1::arrayのほうがよいかもしれません。
お礼
プログラムは専門ではないのですが、freeとdeleteはきちんと使い分けています。 配列のときは、delete [] x; として開放しています。 恥ずかしながら、TR1の存在は知りませんでした。 vectorやdequeについても、少し検索してみましたが、とてもデータを扱いやすそうですね。 勉強になります。ありがとうございます。
- Lchan0211
- ベストアンサー率64% (239/371)
> 「mallocによるメモリ確保は辞め、newによるメモリ確保をしなさい」 > という指摘が、書籍でもwebでもありましたので、 > 両方書き、両者を比べているのですが、理由がイマイチ分かりません。 newで確保したメモリはfree()で解放してはいけない malloc()で確保したメモリはdeleteで解放してはいけない という制約があります。 このため、1つのプロジェクトの中で、何の方針もなく mallocによるメモリ確保とnewによるメモリ確保が入り乱れていると 後で解放する時にfreeすべきかdeleteすべきかを間違える可能性があり、 バグのもとになるとされています。 このことから、どちらかに統一すべきであり、 統一するなら、言語レベルでサポートされていて高機能である newで統一すべきということが一般論として言われています。 (参考) http://ja.wikipedia.org/wiki/Malloc#C.2B.2B.E3.81.A7.E3.81.AE.E5.88.A9.E7.94.A8
お礼
wikipedia にmallocに関する記事があるとは、盲点でした。 勉強になりました。 ご回答ありがとうございました。
- ICE_FALCON
- ベストアンサー率56% (63/111)
newはmallocには無い機能があります。 例えばインスタンスをnewで生成する場合には、 引数付のコンストラクタを呼び出せます。 Hoge *h = new Hoge(1); 他にはnewは失敗した場合、例外を投げることができます。 new[]は他の回答者さんの仰る通りvectorを使う方がお手軽ですが、 STLを使いたくない等の理由がある場合は、new[]を普通に使います。
お礼
newにはそんな使い方もできたのですね。 これは知りませんでした。 malloc単体では例外を投げることが出来ないのも納得です。 STLは出来れば避けたいので、newでやってみようと思います。 ご回答、ありがとうございました!
- jacta
- ベストアンサー率26% (845/3158)
GCCの場合、operator newはmallocを用いて実装されています。mallocに失敗した場合にstd::set_new_handlerで登録した関数を呼び出し、(通常)例外を送出する処理を行うことになるため、どうしてもmallocより遅くなります。 C++ではmallocを使ってはいけないのではなく、非C互換型に対してmallocを使ってはならないと考えたほうがよいでしょう。ただし、正しく使い分けられないのであれば、newに統一したほうが無難なことは確かです。 あと、配列形式のnewも、どうしてもそれを使わなければならない理由がない限りは避けたほうがよいでしょう。普通はstd::vectorを使います。bool型のようにstd::vectorが適切でない場合には、std::dequeを使うとよいでしょう。 MinGWのバージョンに関しては、現状の最新版は4.4.0ですが、-finput-charsetだったか-fexec-charsetだったかが正しく動作しなかったように記憶しています。これでは日本語がまともに使えないので、古いバージョンを使ったほうがましでしょう。 自分でコンパイルし直す手間を惜しまないなら、それもよいとは思いますが...
お礼
gccでは、newの中でもmallocを用いているんですね。 例外処理などで、安全性を高めるためにnewが実装されていると。 なるほど。 std::vectorだと、扱うデータが大きく処理速度が落ち過ぎるようなので、敬遠しています。std::dequeについては知りませんでしたので、勉強させて頂きます。 3.4.5でも、-finput-charsetや-fexec-charsetはきちんと動作してくれませんでした。今はその都度、エスケープしています。 逆に言えば、4.4.0にアップグレードしても、不安要素はそのくらいということですか・・・なら、アップグレードしてしまったほうがいいですね^^; ご回答ありがとうございました!
お礼
vectorで同様の処理を書いていたこともあったのですが、処理が重たくなり過ぎてしまったので、今はやっていません。 コード残しておけば良かったですが。。。どうやって書いてたかな。 MINGW32の標準は3.4.5で、4.x以降は開発版だとどこかで読んでいたので、3.4.5で開発していました。 4.xも検討してみます。 ご回答ありがとうございました。