• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:new と malloc によるメモリの動的確保について)

newとmallocによるメモリの動的確保について

このQ&Aのポイント
  • C++でのメモリの動的確保方法には、newとmallocがあります。
  • mallocはC言語の標準ライブラリであり、newはC++の演算子です。
  • 一般的には、C++ではnewを使用した方が良いとされていますが、mallocの方が速度が速い場合もあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

まあ, operator new[] は operator delete[] のための管理情報を追加しなきゃならないのでどうしても malloc より遅くなる (少なくとも「速くなることだけはない」) んですけどね.... どうしても速度が欲しいなら malloc, お手軽を求めるなら std::vector を使うのが普通かな. ああ, 今どき 3.4.5 もどうかと思うので 4.3.3 なり 4.4.2 にするってのも考えるべきかと.

popo83
質問者

お礼

vectorで同様の処理を書いていたこともあったのですが、処理が重たくなり過ぎてしまったので、今はやっていません。 コード残しておけば良かったですが。。。どうやって書いてたかな。 MINGW32の標準は3.4.5で、4.x以降は開発版だとどこかで読んでいたので、3.4.5で開発していました。 4.xも検討してみます。 ご回答ありがとうございました。

その他の回答 (8)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.9

> ごめんなさい、理解できません。 > 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> >; とすることになるのでしょうが。

popo83
質問者

お礼

実は記憶域期間の問題も抱えていて、別の形で質問させて頂こうと思っています。 STL等が十分に使える環境では、積極的にvectorを使ったほうが良さそうですね。 コメント頂いたキーワードから、知識の幅が広がりました。みなさん、ご回答ありがとうございました。

回答No.8

> 単に動的に割り付けたいだけなら、十分かと思います。 ごめんなさい、理解できません。 arrayの要素数は静的に決まるかと。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.7

> arrayは固定長なのでmalloc/newの代わりにはなりません。 可変サイズにするならそうですね。 単に動的に割り付けたいだけなら、十分かと思います。

回答No.6

> std::tr1::arrayでもよいと思います。 arrayは固定長なのでmalloc/newの代わりにはなりません。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

freeとdeleteを間違うようなプログラマは、(もっと紛らわしい)deleteとdelete[]を確実に使い分けられるとは思えません。 理想をいえば、そんなプログラマを使わないのが一番ですが、そうもいかないのであれば、配列形式のnewは全廃したほうがよいでしょう。 代わりはstd::vectorが最有力ですが、TR1が使える環境であれば、std::tr1::arrayでもよいと思います。std::vectorやstd::dequeを使う場合、push_backやinsert後に反復子が無効になるので、フールプルーフを考えると、std::tr1::arrayのほうがよいかもしれません。

popo83
質問者

お礼

プログラムは専門ではないのですが、freeとdeleteはきちんと使い分けています。 配列のときは、delete [] x; として開放しています。 恥ずかしながら、TR1の存在は知りませんでした。 vectorやdequeについても、少し検索してみましたが、とてもデータを扱いやすそうですね。 勉強になります。ありがとうございます。

  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.4

> 「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

popo83
質問者

お礼

wikipedia にmallocに関する記事があるとは、盲点でした。 勉強になりました。 ご回答ありがとうございました。

回答No.3

newはmallocには無い機能があります。 例えばインスタンスをnewで生成する場合には、 引数付のコンストラクタを呼び出せます。 Hoge *h = new Hoge(1); 他にはnewは失敗した場合、例外を投げることができます。 new[]は他の回答者さんの仰る通りvectorを使う方がお手軽ですが、 STLを使いたくない等の理由がある場合は、new[]を普通に使います。

popo83
質問者

お礼

newにはそんな使い方もできたのですね。 これは知りませんでした。 malloc単体では例外を投げることが出来ないのも納得です。 STLは出来れば避けたいので、newでやってみようと思います。 ご回答、ありがとうございました!

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

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だったかが正しく動作しなかったように記憶しています。これでは日本語がまともに使えないので、古いバージョンを使ったほうがましでしょう。 自分でコンパイルし直す手間を惜しまないなら、それもよいとは思いますが...

popo83
質問者

お礼

gccでは、newの中でもmallocを用いているんですね。 例外処理などで、安全性を高めるためにnewが実装されていると。 なるほど。 std::vectorだと、扱うデータが大きく処理速度が落ち過ぎるようなので、敬遠しています。std::dequeについては知りませんでしたので、勉強させて頂きます。 3.4.5でも、-finput-charsetや-fexec-charsetはきちんと動作してくれませんでした。今はその都度、エスケープしています。 逆に言えば、4.4.0にアップグレードしても、不安要素はそのくらいということですか・・・なら、アップグレードしてしまったほうがいいですね^^; ご回答ありがとうございました!