質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

737閲覧

newで確保したメモリが解放できなくなる時とは

kyota1

総合スコア6

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

2クリップ

投稿2022/06/01 21:58

とある本にこんな記述がありました。
『例えばnewで確保してそのアドレスをpというポインタに入れておくとします。そしてこのpを別の変数に保存したりdeleteしたりしないままpの値を変えてしまうと、もうそのアドレスを保持しているポインタが1つも無くなってしまいます。こうなると、もうこのメモリは自分で解放することが二度とできなくなってしまいます。』

『deleteしたりしないままpの値を変えてしまうと』というのはポインタ変数がはアドレスを変更できるため、元のメモリ部分がdeleteできなくなってしまうのはわかるのですが、
『pを別の変数に保存したり』という部分がわかりません。
教えてください。よろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2022/06/01 22:09 編集

p = アドレス; p = 別のアドレス; この二行で最初のアドレスが何だったかわからなくなるという意味です。 ただの日本語の読解問題なので、意味がわからないときは、意味がわからない文の前後も含めて読み直してみましょう。 次のように別の変数に保存すれば大丈夫です。 p = アドレス; q = p; p = 別のアドレス;
Zuishin

2022/06/02 00:18

ああ、「保存したことが原因で消え失せる」と読む人がいる時代ですか。「保存」という日本語の意味が通じなくなっているというのは少しカルチャーショックですが、保存というのは無くさないためにする行動のことです。 例えば「おかずを少し保存しておく」というのは、食べたり捨てたりせず、後から食べられるようとっておく意味になります。
thkana

2022/06/02 00:24

そもそも「メモリを確保する」とはどういうことか、あるいはもっと戻って「ポインタって何」ということについての理解は自信がありますか? なんかその辺があやふやなのでこの質問になっている気がするのですが。
fana

2022/06/02 01:30

> このpを別の変数に保存したりdeleteしたりしないままpの値を変えてしまうと、もうそのアドレスを保持しているポインタが1つも無くなってしまいます。こうなると、もうこのメモリは自分で解放することが二度とできなくなってしまいます まぁ,やや文章がおかしいとは思う. 要は, (deleteする前に)pの値(アドレス)を何かしら別の変数に値を保存することもなしにpの値を変えてしまうならば,元のpの値(アドレス)を保持する変数がなくなってしまうのだから,deleteできなくなる. …ということを言いたいのでしょう.
tmp

2022/06/02 01:50 編集

「このpを別の変数に保存したり」を疑問に思うということは、 「このpを別の変数に保存したりdeleteしたりしないままpの値を変えてしまう」を  このpを別の変数に保存する(保存してpの値を変えてしまう)  このpをdeleteしないままpの値を変えてしまう ととらえていませんか?  このpを別の変数に保存しないままpの値を変えてしまう  このpをdeleteしないままpの値を変えてしまう なら疑問はなくなりますか?
kyota1

2022/06/02 12:05

皆さんありがとうございます。funaさん、tmpさんで気がつきました。その通りです。 thkanaさん、もう少し知識があれば気がつけたかもしれませんね
Zuishin

2022/06/02 22:43 編集

日本語の知識が必要ですね。 プログラミングほとんど関係ないただの日本語の読み書きの問題なので。 > そしてこのpを別の変数に保存したりdeleteしたりしないままpの値を変えてしまうと、 保存と delete の直後にどちらも「したり」とついていますよね? これで保存と delete が同格に書かれていることがわかり、「しない」が両者にかかっていることがわかります。 delete の後の「したり」が無かった場合は曖昧な表現になりますが、この表現であれば誤解の余地はありません。 「保存」の意味を知っていればなおさら迷うことはないでしょう。
guest

回答3

0

ベストアンサー

『deleteしたりしないままpの値を変えてしまうと』というのはポインタ変数がはアドレスを変更できるため、元のメモリ部分がdeleteできなくなってしまうのはわかるのですが、『pを別の変数に保存したり』という部分がわかりません。

  • pを別の変数に保存する
  • deleteしないままpの値を変える

のどちらかでもうそのアドレスを保持しているポインタが1つも無くなってしまいます、

と読んだのかもしれませんが、

  • pを別の変数に保存する
  • deleteする

このどちらかを行う前にpの値を変えてしまうと、もうそのアドレスを保持しているポインタが1つも無くなってしまいます。

という文章です。(deleteしてもそうなるだろというのはさておき)

pを別の変数に保存せずpを書き換えると確保したアドレスがわからなくなるから開放できなくなる。
これを防ぐには書き換える前にちゃんとdeleteするか、もとのpの値を別の変数に退避しておきなさい

ということです。

投稿2022/06/01 23:39

編集2022/06/01 23:47
ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyota1

2022/06/01 23:58

別変数に保存するだけではなくならないということですよね?
ozwk

2022/06/02 05:39 編集

はい x=100 y=x としたときにxに入っている100という数値は消えませんよね? これと話は一緒です。
guest

0

p の値を別の変数に代入しとけば、その別の変数からdeleteすることができます


メモリを確保すれば、その確保した場所の先頭アドレスが得られます
そして、その確保した場所を開放しようとしたら、その先頭アドレスを持ってきてdelete関数を呼び出します
もしも、そのアドレス値がわからなくなったら、delete関数で開放できなくなります。
開放したいなら、どういう形でも、そのアドレス値を忘れないでおこう、ってことになります

そんだけのはなしです

投稿2022/06/01 22:19

編集2022/06/02 00:56
y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

データはメモリってとこに設置されます。
そのメモリにはスタック領域とヒープ領域があるようです。

スタック領域は普通の変数、int型のint a;とかみたいなやつのデータが設置されます。
ですが、ここは容量が制限があります。配列みたいにサイズに上限があるのです。
そこでヒープ領域っていう、動的に確保するための部分があります。ここにnew/delete等を用いて必要な分確保します。ですがここに設定されたデータはプログラマが手動で破棄しないといけません。OSによってはプログラムが終了したときに自動的に破棄する場合もあるようですが、常駐するようなものだと…

で、ポインタはそのメモリのアドレス(住所)を保持して使うためのものです。

指し示しているアドレスを変えてしまうと、元々指していた場所のデータは破棄されていないならずっと存在していますよね。

では例えば100KB分確保して別の200KBを更に確保したとします。本来なら100KBのやつは破棄されているべきですが忘れていたとします。
そうなると100+200=300KBも所有しています。100KB余分ですね。ではこの処理が数回行われるとしたらどうでしょうか?
余分なデータがかなりありますね。

でも質問にあるような方法でやっている(つまり同じ名前のやつ)やつでやるならそれぞれ100KB分の場所が不明なはずです。
そうなると破棄しようにもできません。

こういうことかと。

投稿2022/06/01 22:33

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問