
C++の
delete[]と、delete演算子の明確な違いとその使い分けについて
型* ptr = new 型[要素数];
でnewしたものについては、
delete[] ptr;
にて、開放
型* ptr = new 型();
でnewしたものは、
delete ptr;
するものだと、覚えてました、
特に深くは考えていなかったのですが。
std::auto_ptr<T>
では、内部的には、delete[]ではなく
deleteをしているという文章を見ました。
{
std::autoptr<型A> iptr;
iptr = new 型A;
}
のようなときは
いいのですが・・・
{
std::auto_ptr<char> cptr;
cptr = new char[n+1];
}
のようなときは、
動的配列なので、内部的に
delete ptr;
になってしまいます。
このように、テンプレートクラスを自作するときに
実際の特殊な型が決定されるまで、
deleteで、いくのかdelete[]でいくのか決定できないのはつらそうです。
そこで、deleteと、delete[]の正しい意味を
知りたいのですが。
Javaや、.NETには、配列オブジェクトというものが
あります。
C++で、
new char[n+1];
は配列オブジェクトでしょうか?
だとすると、delete[]は
右に来たものが配列オブジェクトなら、
Lengthを(こんなものがあるとして)調べて
1つづつ、まわして、deleteのほうを使ってひとつひとつ開放していく。
右に来たものが配列オブジェクトでなければ
deleteと同じ振る舞いをする。
という動きが物理的に考えれそうで。
delete[]と書いておけば、状況に応じて、
動的配列なら全要素サーチして、開放そうでなければ
deleteという風に、勝手に自動でそうしてくれるなら、
どんなときでも、delete[]にするようにコードを書いておけばよさそうです。。
実際のところどうなんでしょうか?
deleteと、delete[]の明確な意味の違いと、
使用方法の違いについて教えてください。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
> new char[n+1];
> は配列オブジェクトでしょうか?
JIS X3014:2003の5.3.4 new式の段落5には、「割付けたオブジェクトが配列の場合」という記述が出てくるので、一応は配列オブジェクトなんだと思います。ただし、Javaや.NETの同名のそれとは別物です。
(C/C++における「オブジェクト」は、概ね「変数」の意味です)
> 右に来たものが配列オブジェクトでなければ
> deleteと同じ振る舞いをする。
これを実現するためには、配列かどうかを調べるためのフラグをどこかに仕込んでおく必要があります。つまり、それだけオーバーヘッドになるわけです。そんな機能が必要なら、そういうスマートポインタを自作した方がいいです。
auto_ptrでは、確かに
template <typename T> class auto_ptr<T[]>;
というのを特殊化してやれば、(delete式に関しては)配列も扱えそうな気がしますが、添え字演算子の多重定義をするかどうかなど、セマンティクスが変わるので、あまり有益ではありませんね。
No.2
- 回答日時:
> std::auto_ptr<char> cptr; cptr = new char[n+1];
この例なら、std::string (または std::vectorあたり)が適当では?
new[]は主にC言語との互換用/最適化用のためにあるもので、
動的配列はSTLのコンテナ等を使えばよいもの。auto_ptrは単体オブジェクト専用です。
> deleteで、いくのかdelete[]でいくのか決定できないのはつらそうです。
RAIIとか考慮したC++ソースではdelete/delete[]って自分で呼ぶことはほぼ無いですし、
単複がブレても定義と初期化(new/new[])だけの問題ですから、ここは多分間違えないでしょう。
知らない初心者がハマるとか、うっかり間違え易い点は同意ですが、
自分でdeleteするようなコードは慣れてから書けばよく、
初心者がdelete/delete[]を自分で書くのが間違ってると私は思います。
# 生メモリの操作を素人にSTLより先に教えるのがおかしいと思う。
> は配列オブジェクトでしょうか?
C++に配列というオブジェクトはありません。
> という動きが物理的に考えれそうで。
そうすることもできたでしょうが、自動でこういう動きはしません。
> どんなときでも、delete[]にするようにコードを書いておけばよさそうです。。
言語設計がnew/delete、new[]/delete[]のペア前提なので、
newでは要素数等を保持せずnew[]でのみ保持する実装が可能です。
つまり、現状C++では問題が出る可能性があり、やってはいけません。
少しでも無駄な処理/メモリを削れる設計のためでしょう。(そういう言語です>C++)
> どんなときでも、delete[]にするようにコードを書いておけばよさそうです。。
現行C++でこれを実現したい場合、new T;を使わず常に new T[1];とすることはできます。
# C++ ではnew[]の他に、単体専用に効率のよいnewも用意されていると考えたらどうでしょう。
>この例なら、std::string (または std::vectorあたり)が適当では?
std::auto_ptr<char> cptr;
なんぞ使わず、普通に
std::stringで問題ないですね。
>動的配列はSTLのコンテナ等を使えばよいもの。>auto_ptrは単体オブジェクト専用です。
そうでした。コンテナを使えば単体オブジェクト
専用でも気にする必要もなかったです。
>少しでも無駄な処理/メモリを削れる設計のためでしょう。(そういう言語です>C++)
そういう言語なんですね。
>現行C++でこれを実現したい場合、new T;を使わず常に new T[1];とすることはできます。
なるほど、そこまですることもないですが。
どうしても、deleteとdelete[]の違いのせいで、
テンプレートが作れないで悩むような時が
あったら、その
「new T[1];」も1つの選択肢として覚えておきます。
># C++ ではnew[]の他に、単体専用に効率のよいnewも>用意されていると考えたらどうでしょう。
それでわざわざ、2種類あるんですね。
なんのために、いちいち使い分けてんだろ。
めんどくせーとおもってましたが。
これで納得しました。
No.1
- 回答日時:
> new char[n+1];
> は配列オブジェクトでしょうか?
NO.
delete も delete[] もメモリの解放という意味では同じです。
確保された領域を一気に解放します(部分的に解放できません)。
# mallocでどれだけ確保してあろうがfreeで解放されるのと同様。
異なるのはデストラクタを1回動かすか、それとも"確保された領域/一つのインスタンスが占める大きさ"回動かすか、の違いとなります。
>異なるのはデストラクタを1回動かすか、それとも"確>保された領域/一つのインスタンスが占める大きさ"回動かすか、の違いとなります。
このくだりを聞くと、
delete[]のいっぽん槍でいけそうに聞こえる。
No2さんは、それはやめたほうがよいと、
記述しています。
いづれにせよ。
単体オブジェクト専用のdeleteを内部でやってますが、コンテナを使えばよさそうなのでそうします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- マウス・キーボード Deleteキーを同時押しで入力できるようにするソフト 2 2023/08/10 21:55
- MySQL 下の画像はSQLの4大命令の性質をまとめたものであるらしいです UPDATE INSERT DELE 1 2023/06/07 15:36
- Access(アクセス) アクセス 削除するレコードを含んだテーブルを指定してくださいのエラー対処方法 1 2022/11/24 15:01
- 英語 Osteogenesis in group B and C were significantly l 2 2022/03/24 05:27
- その他(パソコン・周辺機器) キーボードの「backspace」と「delete」の違いは何でしょうか? 7 2023/08/17 22:22
- Visual Basic(VBA) VBA 行削除した連番 4 2023/06/27 16:00
- Visual Basic(VBA) シート削除のマクロで「deleteメソッドは失敗しました」となります。助けてください! Sub 不要 6 2022/09/08 16:41
- フリーソフト USB内のフィアルの復活ソフトは? 4 2023/03/25 08:54
- Visual Basic(VBA) 今日の日付が過ぎたらその行を削除したい 1 2023/04/01 20:06
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA セル範囲をVariant変数に代入
-
[VB6/VBA] Variant型配列リテラ...
-
メニューを外部から呼び出したい
-
教えてください
-
javascriptですか?
-
javascriptのエラー
-
会員向けページ アクセス制限
-
入力チェック
-
初心者向けのjavascript参考書
-
NNのonloadでは
-
ブラウザからエクセルを開く方法
-
ThickBoxとjavascriptオフユー...
-
IEの右クリックメニューからの...
-
WEBブラウザから任意フォルダを...
-
JSPの処理の途中で、JavaScript...
-
FlashLiteで通信ゲームを作れま...
-
VBA 数(可変)分だけ順に記...
-
jqueryのglossが動いたり動かな...
-
正規表現について
-
javascriptの大量読み込みのス...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
delete[]と、delete演算子の明...
-
Excel vba 配列内の最大値を求...
-
エクセルのVBAでオブジェクトの...
-
コードの意味 ("Scripting.Dict...
-
VBでこんなことできますか??
-
ASPでACCESSマクロのChoose...
-
VB2008で数字の桁数を調べる...
-
[VB6/VBA] Variant型配列リテラ...
-
六角形のマスの作り方
-
どんなオブジェクトでも表示で...
-
VBA 多次元配列のクイックソー...
-
文字認証の問題
-
if(1){...}とはどういうことで...
-
JSPの処理の途中で、JavaScript...
-
フォルダを自動で開く
-
正整数の半角数字かどうか判定する
-
VB.NET2003 テキストボックスに...
-
JavaScriptでショートカットキ...
-
以下のコードを実行しても、オ...
-
デザイン時のVisible=Falseは実...
おすすめ情報