- ベストアンサー
new charとnew char[N]の違いは?
こんにちは。 C++言語において、動的なメモリの割り当てを行うために、new演算子がありますが、 char *p; p=new char; とした場合と、 char *p; p=new char[80]; とした場合、何が異なるのでしょうか? pに1次元配列を割り当てる場合は、後者の方が正しいと思うのですが、 どちらの場合も、pはchar型の1次元配列として扱う事ができました。 ただ、それはたまたまだったのかもしれないので、きちんと理解しておきたいと思います。 何か御存じの方がいらっしゃれば、是非アドバイスを頂きたいと思います。 では、よろしくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
横道に逸れますが、後学の為に。 ># new char[1]やnew char[0]の時は…どうなるんだ?<未検証 new []した物をdelete []せずにdeleteした場合、先頭の1要素に対してのみしかデストラクタが呼ばれません。 delete[]した場合は、すべての要素に対してデストラクタが呼ばれます(要素が100個あればデストラクタが100回呼ばれる) なので、new char[1]した物の場合、delete []とdeleteは、同じ動作(先頭の1要素に対してのみデストラクタを呼ぶ)をしますので、問題は起きません。 一応、new[]したらdelete[]しないとなりませんが、デストラクタの定義が無い単純変数の配列を開放する場合、delete[]しないでdeleteしちゃっても、問題は起きません(けど、なるべく、仕様には従うべき) また、要素数を0個にしたnewは、要素数が0個の配列を返すので、delete、delete[]共に、デストラクタは呼ばれず、メモリの開放のみが行われます(と言う仕様になっている筈だが、コンパイラによっては、new [0]がNULLを返しやがる事がある。要素数0個の配列にはアクセスしてはいけないからnewしてもdeleteしか出来ないので、事実上、問題は起きないが)
その他の回答 (4)
- Wr5
- ベストアンサー率53% (2173/4061)
>har *p; char *p; です。コピペで切れた……
- chie65536(@chie65535)
- ベストアンサー率44% (8752/19860)
因みに p[0] のように「pを1次元配列のように記述する」って話と「pが指す先に、何個分のcharがあるか?」って話は「まったく関係ない話」なので、注意しましょう。 pが指す先にメモリがあろうがなかろうが、p[0]のような記述は「いつでも可能」です。
お礼
御丁寧にありがとうございます。 仰る通りだと思います。
- Wr5
- ベストアンサー率53% (2173/4061)
deleteする時にも違いがありますのでご注意を。 char *p; p=new char; ならば delete p; ですし、 har *p; p=new char[80]; ならば delete[] p; です。 # new char[1]やnew char[0]の時は…どうなるんだ?<未検証
お礼
御回答ありがとうございます。 僕の環境では、なぜか char *p; p=new char[80]; の場合で、 delete p; としても、エラーになりませんでした。
- chie65536(@chie65535)
- ベストアンサー率44% (8752/19860)
>何が異なるのでしょうか? 「そこに、何個分のcharがあるか?」だけが違います。 p=new char; とした場合、pが指すメモリには、charが1個分しかありません。 2番目以降を読み書きしようとすると、場合によっては「不正なメモリアクセス」でプログラムが停止したり、他の変数の値を壊します。 p=new char[80]; とした場合、pが指すメモリには、charが80個分しかありません。 81番目以降を読み書きしようとすると、場合によっては「不正なメモリアクセス」でプログラムが停止したり、他の変数の値を壊します。 このように「1個か80個かの違いがあるだけ」で、他は何も違いません。 つまり p=new char; は p=new char[1]; と同じです。 p=new char[1]; と p=new char[80]; の違いを比べれば「1個か80個かの違いがあるだけで、他は何も違わない」のは明白です。
お礼
御回答ありがとうございます。 なるほど、p=new char は p=new char[1] と同じなのですね。 よーく分かりました。
お礼
御丁寧にありがとうございます。 >new []した物をdelete []せずにdeleteした場合、先頭の1要素に対してのみしかデストラクタが呼ばれません。 それは知りませんでした。 だから、 char *p; p=new char[80]; の場合で、 delete p; としても、エラーにならなかったのですね。 すっきりしました。