New演算子をつかうコードをよく見ますが、(以下参照。)なぜ、new演算子を使わないといけないのかわかりません。
また、変数宣言なら、スタック、new演算子なら ヒープ領域確保する。
こちらの、スタック、ヒープ領域の意味がよくわかりません。
#include <iostream>
int main()
{
int buf = 100;
//これはできない //int nums[buf]; int *nums = new int[buf]; for (int i = 0; i < buf; i++) { nums[i] = i; } std::cout << nums[0] << std::endl; std::cout << nums[50] << std::endl; std::cout << nums[99] << std::endl; //newしたものはdeleteする delete[] nums; std::cin.get();
}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/09/06 07:26
2021/09/06 07:30
2021/09/06 07:49
退会済みユーザー
2021/09/06 08:03
2021/09/06 08:11
回答4件
0
newを使う理由:
このコードについて言えば,
//これはできない
//int nums[buf];
とご自身で言っているじゃないですか.
ある方法ではできないのだから,何かしらそれとは別の方法でやるしかない.
(とにかく,言語の仕様的に許してくれないのだから仕方ない)
で,その別の方法が new だった.
「このコードでnewを使っている理由」はその程度のことでしょう.
スタック、ヒープ領域の意味がよくわかりません
こちらについては「とにかくたくさん検索してください」と言うのが手っ取り早いと思う.
(投げやりな回答というわけじゃなくて,いくつも説明が見つかると思うから)
で,それはそれとして,
//スタック領域が使われる? SomeType Instance;
と
//ヒープ領域が使われる? SomeType *pInstance = new SomeType();
の違いを実際上考える際には,
主たる関心はオブジェクトの生存期間に関する事柄なのであり,「なんとか領域が使われる(らしいぜ)」とかいう話は正直割とどうでもいい.
領域の種類に関して考えることがあるとしたら,
「スタック領域」のサイズというのは(一般に?)そこそこ小さくて,「使いすぎていっぱいになっちゃった」ということが(他種の領域と比べて)起きやすいので,それを避けるために,巨大なオブジェクトは「スタック領域」じゃない領域が使われるようにしてやるぜ!
…っていう話はある.
(逆に言えば,「スタックあふれちゃった」状態にまず到達しないだろうと見込めるならば,そのことをnewを使う理由にする必要は無い)
投稿2021/09/06 08:30
総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
まず、通常、文字列や数値などのデータはスタック領域(Stack area) に保存されます。
でも、このスタック領域、サイズが決まっており、整数一個とかなら問題ありませんが、
Webブラウザのタブみたいに複数必要だったり、構造体やクラスとかのような、物によっては相当デカいものだと、保持するのが大変です。
そこで、ヒープ領域(Heap area) と呼ばれる場所で、動的に確保する事で、メモリが許す限り保持できます。
ただし、これにも欠点があり、「自分でお片付けしないといけない」というのがあります。
スタック領域だと、関数のブロックから抜けるとかのような、「もうこれ以上使わんだろ」と思う場合は勝手にデリートされます。(返還される)
でも、ヒープ領域は開発者自身が「この領域にあるデータを破棄せよ」と命じないとずーーーーっと残ったままです。
(OSによっては実行ファイルが終了するとOS自身が破棄してくれるようですが)
その「ヒープ領域のここからこの分確保するぞ!」っていうのはC言語だとmalloc, C++だとnewに相当するものです。
「あー、(ヒープ領域の)ここにあるデータ、もう使わないから破棄だわ」というのがC言語だとfree, C++だと delete に相当するものです。
(ちなみにJavaとかのような言語だと、ガーベージコレクタ(GC)と呼ばれるものがdeleteしてくれるようです)
仮に、実行ファイルが閉じられるとOSがお片付けしてくれるとしても、
Webブラウザや常駐型のものだと、そこの部分はずーーーーーーっとあるので、メモリをひっ迫してしまいます。
なのでnewをするのなら、不必要になればdeleteするのがマナーです。
参考: メモリの動的確保(配列など)
そして、今回のコードですね。
今回のコードを見ると、
C++
1int buf = 100; 2 3int *nums = new int[buf];
となっていますね。
これは、動的にメモリ、つまりヒープ領域を確保しています。
で、最後は不要になったので、deleteで破棄。
要素数がはっきりとわかっている場合は普通の配列でもいいですが、要素数が実行時にしかわからないこともあります。
さらに、構造体やクラスの配列 ( Class1 objs[100] のような ) の場合もあります。
構造体やクラスなんかはメンバの分だけ重くなります。
(メンバ関数は関係ないっぽいが)
スタック領域だとその分ひっ迫します。
サイズによってはオーバーフローを起こします。
そのため、サイズが(実行するまで)不定だったり、オブジェクトのサイズがデカい場合はヒープ領域に確保する事があります。
int型とかだと 4バイトとかなのですが、構造体やクラスの場合はメンバ(メンバ変数)分、必要になるので、C++だとnew/deleteで確保する事が多いのです。
それを見習って(?) Javaとかでは new を使う方式でやるようです。
[追記1]
※ 他の回答者の方のアンサーを見て、ちょっと思ったので追記。
確かに単純にデータ列を確保するのなら new/deleteよりも std::vectorやstd::listを使ったりしますね。
ですが、クラスオブジェクトを生成する場合は良く使います。(モダンなものだとスマートポインタと呼ばれる、std::shared_ptr とかを使うようですが)
単純にint型データの配列のような場合はnew/deleteをするぐらいならstd::vectorを使います。
投稿2021/09/06 08:04
編集2021/09/06 08:08総合スコア4962
0
なぜ、new演算子を使わないといけないのかわかりません。
これはnew
-delete
の教科書的な例です。
実用的には、(よほど性能やメモリ消費に対する要求が強く、細やかな制御が必要となる場合は別ですが)C++ではvector
やarray
のようなSTLコンテナを使ったほうが便利で安全なコードが書けます(自分でnew
を書く必要もありません)。
「要素数が不明だ」というだけでnew
を使うのはおすすめできません。
投稿2021/09/06 07:33
総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/09/06 07:40
2021/09/06 07:47 編集
退会済みユーザー
2021/09/06 07:55
2021/09/06 07:57
退会済みユーザー
2021/09/06 08:02
2021/09/06 08:06 編集
2021/09/06 08:39
0
[ご参考] スマートポインタを使うと...
C++
1#include <iostream> 2#include <memory> // unique_ptr, make_unique 3 4int main() { 5 int buf = 100; 6 7 //これはできない 8 //int nums[buf]; 9 10 std::unique_ptr<int[]> nums = std::make_unique<int[]>(buf); 11 12 for (int i = 0; i < buf; i++) { 13 nums[i] = i; 14 } 15 16 std::cout << nums[0] << std::endl; 17 std::cout << nums[50] << std::endl; 18 std::cout << nums[99] << std::endl; 19 20 std::cin.get(); 21 22 // "newしたものはdeleteする"のは unique_ptr まかせ 23}
投稿2021/09/06 23:16
総合スコア16612
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。