ページ 1 / 1
deleteとNULL初期化
Posted: 2014年2月27日(木) 20:00
by sql
deleteとnull初期化について聞きたいことがあります
座標(0,0)から右に向かって移動する円を管理するマネージャークラスを作ったのですが聞きたいことがあります。
コード:
//ヘッダー
Sphere sphere[10];
//cpp
SphereMgr::SphereMgr()
{
for(int i = 0 ; i < 10 ; i++)
sphere[i] = NULL;//null初期化
}
SphereMgr::~SphereMgr()
{
delete[] sphere;
}
SphereMgr::create()
{
static int count = 0;
count++;
if(count % 10 == 0)
{
for(int i = 0 ; i < 10 ; i++)
{
if(sphere[i] == NULL)
{
sphere[i] = new Sphere();
break;
}
}
}
}
SphereMgr::calc()
{
for(int i = 0 ; i < 10 ; i++)
{
if(sphere[i] != NULL)
{
sphere[i]->calc();
if(/*画面外に出たら*/)
{
delete sphere[i];
sphere[i] = NULL;
}
}
}
}
ここで40行目のdeleteをせずに(コメントにして)41行目でNULLで初期化したところ、しっかり11コ目~が出てきました。
deleteとNULL初期化の決定的な違いがわかりません。
deleteだけやってはNULLではないので11コ目~はでないと思いますが、NULLの前にdeleteを書く理由が知りたいです。
このdeleteがないとどのようなことが起きるのでしょうか?
龍神録C++でもやっていたので(それと「nullptr」とはなんなのでしょうか?)
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:06
by h2so5
それは基本的なことなので、いちどC++の入門書を読むことをお勧めします。
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:16
by sql
参考書を見てもイマイチ実感が湧かないから質問したのですが・・・・
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:21
by N.R
参考書には delete は何をするものだと書いてありましたか?
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:24
by sql
もしかして回答された方は二重解放のことを調べて欲しいと思っているなら表現を変えます。
載せたコードでdeleteしないでnullで初期化(41行目)だけやるとdeleteした場合とメモリとかどこか違ってくる要素があるのでしょうか?
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:26
by 白い時空
deleteはnewで作成した物を捨てる行為ということになります。
NULL初期化は単なる数値の代入だけなのでこの捨てるという行為をしません。
よってdeleteを無視すると、捨てたことにしたにもかかわらず実際は捨てていないので、不要なゴミがメモリ上に溜まってしまうわけです。
簡潔に書くとこんなかんじですかねえ。
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:28
by sql
白い時空 さんが書きました:deleteはnewで作成した物を捨てる行為ということになります。
NULL初期化は単なる数値の代入だけなのでこの捨てるという行為をしません。
よってdeleteを無視すると、捨てたことにしたにもかかわらず実際は捨てていないので、不要なゴミがメモリ上に溜まってしまうわけです。
返信ありがとうございます。
聞きたかったことはそれです。
ありがとうございました。
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:35
by usao
>delete[] sphere;
これもまずいですよね.
>載せたコードでdeleteしないでnullで初期化(41行目)
これを”初期化”とは呼びません.
オフトピック
>いちどC++の入門書を読むことをお勧めします。
激しく同意です.
基礎的な部分をちゃんとやらずに
断片的な事柄だけを掲示板で訊きまくっていても碌に身につかないのではないかな,と危惧します.
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:39
by N.R
あなたの参考書に白い時空さんの回答が書かれていなかったのなら
参考書選びから考えた方がいいですね
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 20:42
by sql
N.R さんが書きました:あなたの参考書に白い時空さんの回答が書かれていなかったのなら
参考書選びから考えた方がいいですね
おすすめの参考書とかありますか?(個人的にでいいので)
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 21:07
by sql
返信ありがとうございます(見逃していました)
usao さんが書きました:>delete[] sphere;
これもまずいですよね.
これはなぜいけないのでしょうか?参考書には配列の解放はこのように書いていたのですが・・・
newする前に呼ばれたらマズイから・・・でしょうか?
usao さんが書きました:>載せたコードでdeleteしないでnullで初期化(41行目)
これを”初期化”とは呼びません.
失礼しました。
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 21:16
by N.R
私が参考にした書籍は非常に良いものでしたがもう20年以上前の話で
今はもっと良いものがWEBで参照できると思いますが私自身が参考にしたわけではないので紹介は控えます。
ただ delete C++ でぐぐっただけでも
http://www.geocities.jp/ky_webid/cpp/language/012.html
このくらいのものは出てきます。
ここだけでは不十分とか思うなら、1ページ見て自分の知りたい事が全てわかる都合のよいものは無いと知ってください。
掲示板で簡単に答えを得ようとした結果がusaoさんの指摘したような解釈を産んでいると思いますね。
>これを”初期化”とは呼びません
「ポインタをNULLで初期化している」という言葉自体に間違いはないですが、sqlさんの考える初期化とは挙動が違うでしょうね
>これはなぜいけないのでしょうか?
delete には遂になる new があるはずです。
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 21:23
by sql
N.Rさん返信ありがとうございます
自分なりの考えなのですが
N.R さんが書きました:>これはなぜいけないのでしょうか?
delete には遂になる new があるはずです。
はデストラクタに
コード:
for(int i = 0 ; i < 10 ; i++)
{
if(sphere[i] != NULL)
delete sphere[i];
}
と書けば良いのでしょうか?
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 21:33
by N.R
×遂に
○対に
ですね
new がないなら delete はいらない。
delete 使うなら new を使う。
(基本的に、ですが)
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 21:43
by sql
N.R さんが書きました:×遂に
○対に
ですね
new がないなら delete はいらない。
delete 使うなら new を使う。
(基本的に、ですが)
自分が初めに書いたコードの24行目でnewしているポインタがまだ画面にある状態(deleteされていない)で不祥事によりデストラクタが呼ばれたらどのように解放するのでしょうか?
ひとつ前の自分のデストラクタの書き方ではダメなのでしょうか?
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 22:00
by N.R
なるほど、それで全部の要素を開放していると考えていたのですね。
それはまた別の話です。
配列の要素1つ1つを開放する必要があります。
(2重開放にも対応する必要があります)
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 22:13
by sql
N.R さんが書きました:配列の要素1つ1つを開放する必要があります。
(2重開放にも対応する必要があります)
サイト(
ここ)で見るとdeleteした後にポインタをNULLで初期化すれば二重解放を回避できると書いてありましたので、そのようにして、
メモリ未確保または画面には出たけど画面外に出てdeleteされたものもdeleteされてしまうと困るので直後にNULLで初期化をしています。(40,41行目)
デストラクタでは、メモリ解放されたorメモリ未確保はNULL値であるので、それ以外(画面に出ている)をdeleteしろ・・・という意味で書いたのですが・・・・
何回も尋ねるようで悪いのですが、自分の書いたデストラクタ(NO.13の)は間違っているのでしょうか?
間違っているか大丈夫(正しい(この場合だとですが))なのかわからないのでモヤモヤしています・・・
Re: deleteとNULL初期化
Posted: 2014年2月27日(木) 23:36
by Poco
No.13で合っています。
No.1のデストラクタは、delete[] sphereに対応するnew[]がないので間違っています。
存在してはいけないdelete[]です。
N.Rさんも仰っていますが、
・newで確保したものはdeleteで解放する
・new[]で確保したものはdelete[]で解放する
・mallocで確保したものはfreeで解放する
これを意識する必要があります。
Re: deleteとNULL初期化
Posted: 2014年2月28日(金) 00:11
by sql
Pocoさん返信ありがとうございます。。
大丈夫なようでホッとしています。
Poco さんが書きました:・newで確保したものはdeleteで解放する
・new[]で確保したものはdelete[]で解放する
・mallocで確保したものはfreeで解放する
これを意識する必要があります。
大切な助言ありがとうございます。
では、これにて。
Re: deleteとNULL初期化
Posted: 2014年2月28日(金) 10:04
by usao
オフトピック
こういうことを何度も言われるのは嫌だろうけども,これは文句とかではなく純粋な 助言 です.
ちゃんと勉強しませんか?
(まぁ,する気は最初からないのだろうな,みたいな邪推もできますけど,一応言ってみる)
少しでもまともにnewとdeleteあたりのことだけでも勉強されたのであれば,そもそも
>deleteをせずに(コメントにして)41行目でNULLで初期化
みたいな謎状態には至らないはずです.
もし仮に
>・newで確保したものはdeleteで解放する
>・new[]で確保したものはdelete[]で解放する
>・mallocで確保したものはfreeで解放する
こういう基本を押さえていないような本で勉強されているのであれば,それは即刻焼却するなり地中奥深くに封印するなりして
本屋に「普通の」C++の入門書を買いにいくべき,とか言うくらいの「基礎」です.
(超個人的見解で言えば,「C++始めました(7日目)」とかいう人物でも余裕で知っているレベルです.)
掲示板にしても,あたなたがNo.17でリンクしているページにしても,
そういう前提知識すら無い状態で局所的な情報だけを見ていても仕方ないですよ.
Re: deleteとNULL初期化
Posted: 2014年2月28日(金) 11:29
by N.R
急いでいたので肝心の事を書いてなかったですね。
No.13の対応で合っています。
失礼しました。
疑問に思った事をつきつめるのは非常に良い事です。
現場でも基本を飛ばして分かったつもりになっている者もザラにいます。
書籍を買わずお金をかけずに勉強したいという姿勢をとやかく言う事もしないです。
しかし疑問の解決は自分で見てみないと意味がないです。
ブレークをはって動きを見てみるなり、リソースモニターを使ってメモリ状況を確認するなり
質問するならその方法です。
掲示板で答えを求めてもWEBに書いてある通りの事か自分で確認しろとしか返しようがないです。