C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

変数の明示的な開放について

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■91308 / inTopicNo.1)  変数の明示的な開放について
  
□投稿者/ ぷら (4回)-(2019/06/15(Sat) 09:01:57)

分類:[C/C++] 

C++におけるグローバル変数など不要になった変数を明示的に開放する方法ありますか?

また、オブジェクトの開放によるクラスの再利用を繰り返し文で実行するのは禁忌という理由はなぜですか?

例:
class A{
・・・
};

int main(){
while(1){
A *a = new A;
delete a;
}

}
引用返信 編集キー/
■91309 / inTopicNo.2)  Re[1]: 変数の明示的な開放について
□投稿者/ WebSurfer (1844回)-(2019/06/15(Sat) 11:03:32)
No91308 (ぷら さん) に返信
> C++におけるグローバル変数など不要になった変数を明示的に開放する方法ありますか?

C++ はすでに忘却の彼方にある自分がレスするのもなんですが・・・

デストラクタというものがあるのですが、それは目的に合いませんか?

そんなことは言われるまでもなく知っているということでしたら失礼しました。
引用返信 編集キー/
■91310 / inTopicNo.3)  Re[2]: 変数の明示的な開放について
□投稿者/ ぷら (5回)-(2019/06/15(Sat) 14:44:40)
私の質問の仕方が悪かったです。
申し訳ありません。私が当初、聞きたかったのは以下の1と2に関する内容です。

補足で3も質問の内容として新たに加えました。

~~~~~~~~~~~~~~~~~~~~~~

1.一番最初に質問した内容なのですが、クラスのメンバ変数でないグローバル変数の場合はどう対処するのですか?
そのままdelete演算子を使用していいのですか?


2.オブジェクトの開放によるクラスの再利用を繰り返し文で実行するのは禁忌という理由はなぜですか?
しっかりと開放しても何か支障をきたすのですか?

例:
class A{
・・・
};

int main(){
while(1){
A *a = new A;
delete a;
}

}


3.デストラクタ内で明示的にdeleteする必要があるのは、クラスのメンバー変数である、ポインタ変数をはじめ、動的変数の一種であるvectorクラス配列、stringクラス等も対象になる認識でいますが合ってますか?
逆にデストラクタに記述しなくても解放されるのは、int型などのクラスのメンバー静的変数のみという認識で合ってますか?
引用返信 編集キー/
■91311 / inTopicNo.4)  Re[3]: 変数の明示的な開放について
□投稿者/ 774RR (698回)-(2019/06/15(Sat) 16:36:21)
言葉に囚らわれすぎていて真に聞きたいのは何かわかりにくいけど

1.
class hoge_type { ... };
hoge_type global_hoge; // 俗にいう大域変数
この global_hoge は「不要にならない」=プログラムの起動から終了までずっと存在し続けて、途中で処分できない。
例えば Windows であれば名前付き mutex を大域変数にすることで二重起動防止とかに使うこともできる。

2.
理論上は何も問題はない。と言いたいところだけど、ヒープ領域の断片化は発生する可能性がある。
C++ はガベージコレクタ系の言語ではないのでヒープの断片化は結構痛い。

だけど、そういう使い方するんだったら単に自動変数でいいよね。
自動変数にしておけば生成廃棄ともコンパイラが全部面倒見てくれるわけだ。
それなのにわざわざ自分で new/delete をやるのは無駄ムダむだ=禁忌って言っていい。

3.
真にやりたいことがわからん。
delete してよいのは new したものだけ。 new してないものを delete するのはバグ。

クラス型の変数を自動変数として作ったなら、
- 変数定義しているところで自動的にコンストラクタが呼ばれて、
- 寿命が尽きるところ=対応するカギかっこ閉のところで自動的にデストラクタが呼ばれる
けど、これはクラスのメンバについても同様。

(基底クラスのコンストラクタ)→メンバ変数のコンストラクタ→自分自身のコンストラクタ
自分自身のデストラクタ→メンバ変数のデストラクタ→(基底クラスのデストラクタ)
と行ってくれるよ。

自動変数を普通に作る際には new しない。当然 delete してはならない。

void test_func() {
    if (...) {
        hoge_type h; // new してないのだから delete してはならない
        ...
    }
    else {
        hoge_type* p = new hoge_type(args); // new したのなら
        ...
        delete p; // delete が必要だけど、先に書いた通りムダ無意味
    }
}

自分のクラスが、
- メンバ変数としてポインタ型変数 hoge_type* p; を持っていて
- コンストラクタ内で new している p=new hoge_type();
ならば
- デストラクタ内で delete しなきゃならない delete p;
だけでなくて deep/shallowコピーについても考えないとバグる。

で、そんな面倒なこと考えるくらいならフツーのメンバ変数 hoge_type h; にしとけば何の問題もない。
ってこと。

引用返信 編集キー/
■91315 / inTopicNo.5)  Re[4]: 変数の明示的な開放について
□投稿者/ ぷら (6回)-(2019/06/16(Sun) 03:25:25)
> 3.
> 真にやりたいことがわからん。

遠まわしすぎて申し訳ありません。
stringやvector配列をクラスのメンバ変数にするとメモリリークを起こすと聞いたので質問させて頂いた次第です。

newによる確保でなくても、動的変数であればデストラクタ内に明示的に開放する処理を書かなければいけないと言われたのですが、774RR様のおっしゃる通り、newで確保したものではないのでdeleteによる解放手段がないということになり疑問に思いました。
引用返信 編集キー/
■91317 / inTopicNo.6)  Re[5]: 変数の明示的な開放について
□投稿者/ 774RR (700回)-(2019/06/16(Sun) 07:39:13)
> stringやvector配列をクラスのメンバ変数にするとメモリリークを起こすと聞いたので質問させて頂いた次第です。
んなわけない。そんなことが本当に起こるのならとっくに問題が指摘され直されている。
世界中に C++ プログラマが何人いると思う?

当該クラスのコピーコンストラクタまたは代入演算子の実装が間違っているだけだと思う。
それこそ shallow/deep のどっちコピーが必要なのかとか。

あるいは「メモリリーク」の解釈の違いだろう。

1.動的確保・解放を繰り返すとヒープ領域が断片化することがある。
すると、「全部合計すれば 1GiB の空きメモリがある」が、その空きメモリは散在して=断片化している、
なんてのは普通にありえて、そうすると 1GiB の連続領域は取れないってことになる。
報告された空き容量(の連続領域)が取れない=リークと呼んでしまうマヌケはいる。

2.タスクマネージャ等のメモリ使用量測定ソフトを使っているとしよう。
解放関数を呼んでもメモリ消費量が減らないのはプログラムの挙動上ごく普通の動き=リークしてないんだが
正しく理解せずに「メモリリーク」と呼んでしまうマヌケもいる。

リークすると言った人にその真意を聞いてみるといい。聞く際にはオイラが書いたみたいなキツい言葉でなくて
オブラートにくるんでみたほうが後々の人間関係に役立つだろう。

ところでメモリ解放とメモリ開放ではどっちが正しいんだろう? なんかゲシュタルト崩壊してきた。
引用返信 編集キー/
■91329 / inTopicNo.7)  Re[6]: 変数の明示的な開放について
□投稿者/ ぷら (7回)-(2019/06/17(Mon) 00:32:55)
No91317 (774RR さん) に返信
>>stringやvector配列をクラスのメンバ変数にするとメモリリークを起こすと聞いたので質問させて頂いた次第です。
> んなわけない。そんなことが本当に起こるのならとっくに問題が指摘され直されている。
> 世界中に C++ プログラマが何人いると思う?

> リークすると言った人にその真意を聞いてみるといい。聞く際にはオイラが書いたみたいなキツい言葉でなくて
> オブラートにくるんでみたほうが後々の人間関係に役立つだろう。


その人に聞いてみたら、うまくはぐかされたような…。
「○○(自分)は、プログラミングで飯を食っていくわけでもないし別にそれぐらいいいだろ(笑)」って言われました"(-""-)"

確かに趣味としてC++の勉強をしていますが、やるからにはしっかりと勉強していきたいです!
個人的に、メモリリークとヒープ領域の断片化について大変勉強になりました。

ありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ