• ベストアンサー

C++のstructが確保される領域について

C++ではstructはクラスとして扱われるそうですが、 確保される領域はスタック領域だと聞きました。 StructHoge *structHoge = new StructHoge; とした場合structHogeに入っているStructHogeインスタンスのアドレスが指し示しているのは  スタック領域なのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

new でとってくるのは通称「ヒープ」と呼ばれる領域. ただし規格上はそもそも「スタック領域」なるものが存在しない.

haraheri31
質問者

お礼

教えて頂き大変ありがとうございました。 認識が間違えていたようです。 因みに、C++には規格上「スタック領域」が存在しないというのはどういうことでしょうか? 詳しく教えて頂きたいです。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

はっきりいってしまうと, 言語の規格上「変数がどのメモリ領域に配置されるのか」というのは瑣末なことでしかありません. 真に大切なのは「オブジェクトが (時間的あるいはソースコード上の) どの範囲で有効なのか」です. 例えば void foo() { int i = 0; for (i = 0; i < 100; ++i) { printf("%d\n", i); } } という関数 (C だけど) では, 変数i が「int i = 0; の行から関数の最後まで有効である」ことさえ知っていれば, どのメモリ領域にあろうと何も問題ありませんよね? その意味で, 規格において「スタック領域」やら「ヒープ領域」やらというものを持ち出す必要はないのです. もちろん「現実の機械」で上のプログラムを使うとすると変数i はスタック領域に置くことになるでしょうが, それはあくまで 「int i = 0; の行から関数の最後まで」という変数i の有効範囲を実現するためにはスタック領域に置いた方が都合がいい だけであって, 規格で強制されているわけではありません.

haraheri31
質問者

お礼

ご返答ありがとうございます。 大変勉強になりました。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

C++はJavaと違ってnew演算子を使わなくてもインスタンスの生成できます。 StructHoge sh; スタック領域で確保されるのは、こういう風にインスタンスを生成する場合です。 ただし#1でいわれているようにC++の規格にスタック領域があるわけではありません。

haraheri31
質問者

お礼

>C++はJavaと違ってnew演算子を使わなくてもインスタンスの生成できます。 >StructHoge sh; >スタック領域で確保されるのは、こういう風にインスタンスを生成する場合です。 C++の構造体はデフォルトのアクセス権が違うだけであとはクラスと同じ振る舞いなんですよね。 ところで、 >ただし#1でいわれているようにC++の規格にスタック領域があるわけではありません。 ↑はどういう事なのでしょうか? 色々検索してみてもC++でスタック領域、ヒープ領域という風に説明されているサイトが多いのですが、 スタック領域がないとすると、何処に確保されるのでしょうか?

関連するQ&A

  • C++のnewで確保した領域について

    こんにちわ。C++を勉強し始めた者です。 new演算子を使ってインスタンスを生成した場合、それはスタックではなくヒープ領域に確保され、不要になったらdeleteを使って領域を解放しなければいけない認識です。 C++の初心者向けサンプルコードを見ていて疑問があったので質問させてください。 (例)クラスA.cpp ======================== #include <Car> #include <Garage> ~略~ クラスAのコンストラクタ{ Car *mycar = new Car("プリウス"); addGarage( mycar ); } クラスAのデストラクタ{ } ======================== 上記のような実装のクラスAがあったのですが、コンストラクタでCarクラスのインスタンス生成をして、オート変数の*mycarに格納して、Garageの公開関数に渡しています。 質問1:このクラスAをインスタンス生成した場合、コンストラクタで確保したヒープ領域は、プログラム終了時まで解放されない認識であっていますか? 質問2:オート変数の*mycarはコンストラクタからreturnした時点で解放されてしまうので、今のままではデストラクタでヒープ領域をdeleteできない認識であっていますか? 質問3:newで生成したインスタンスへのポインタは、その関数内でdeleteしない場合、メンバ変数やstatic変数、グローバル変数に格納しなければdeleteできなくなるという理解であっていますか? 質問4:C++のコードでnewした戻り値をオート変数に格納するプログラムは通常使うことはあるのですか?

  • C++で、メンバもヒープに確保されていますか

    C++でどこまでヒープに確保されるのかが分からなくなる場合があります。 特に、配列がある場合や、クラスを使う場合newしてインスタンス作って使用する場合と、 そうでない場合があり、どこまでヒープ領域に確保されているのか 分からなくなってしまっています。 (開発環境 Visual Studio 2013等) Q1 クラス内の配列 class AA{ public: int x; int dat[10]; }; AA *a0 = new AA(); とする場合と AA a1; とする場合。 このとき、メンバ変数はそれぞれ、 a0->xはヒープ領域に確保 a1.xはスタック領域に確保 されるという理解で良いですか? そして、配列a0->dat[0]等 もヒープ領域に確保されていますか? Q2 クラス内にクラス class BB{ int u,v; AA aa; }; BB *b0 = new BB(); とした場合、 b0がヒープに確保されるとして、 b0->aaはヒープに確保されており、 b0->aa.xやb0->aa.dat[0]等もヒープに確保されているという ことで良いでしょうか? Q3 確認方法 変数等がヒープかスタック領域のどちらに確保されたかは どうやって見分けることができますか? アドレスの値から判断できますか? よろしくお願い致します。

  • mmap()した領域の領域確保

    mmapで特定のデバイスのIOメモリを仮想空間に割り付けて, その領域に対してユーザーからデータを書き込むことを考えています. ユーザープログラム側でその領域上に,ある構造体の双方向リスト を作りたいのですが,ユーザー空間の特定のアドレス範囲から空き メモリ領域を動的に確保する方法はないでしょうか void *vm_malloc(start_address, end_adress, nbyte); とすると"仮想アドレスstart_address~end_adressの範囲から空き領域を探し出し, nbyteバイトの領域を確保する"みたいなイメージです 一連の流れとしては,struct hogeをIOメモリに書き込む場合,  ・mmap()でIOメモリを仮想空間にマップ  ・struct hoge* addr = vm_malloc();でマップされた領域からsizeof(struct hoge)だけ領域を確保  ・*addr = .....;  ・vm_malloc, データの書き込みの繰り返し  ・fsync() のようなことをしたいと考えています.

  • new領域確保について

    お世話になります new演算子の使用方法について教えてください。 new演算子は、動的確保を行なう際に使用する事は知っております。 もう1つの使用理由として、関数内のローカル変数領域が多大になる場合に 使用すると聞いた事があります これは、スタック領域を圧迫しないためと説明を受けた記憶があります これがあってるとしたら、どれくらいの変数容量を宣言する際に、new演算子を使用するのでしょうか? よろしくお願い致します

  • C++で領域の確保の方法

    今C++の勉強中なのですが、 領域の確保の方法でいい方法が知りたいのです。 ポインターのポインターを使って二次元配列の領域を確保したいのですがいい方法が思いつきません。 int **pBox; pBox = new int *[ 10 ]; for( int i=0; i<10; i++ ) { pBox[ i ] = new int[10]; } //ちなみに今はこんな感じのものしか考え付きませんint型[10][10] を確保したつもりです。 間違っていたら教えていただきたいです。 本題はこちらで、もっと効率のいい確保の方法を知りたいのでご協力を よろしくお願いします。

  • newを使った領域の動的確保

    お世話になります。 C++での記述方法なのですが 構造体Testの領域を確保しておいて値を入れます。 確保しておいた領域では領域が不足するときに 不足分を追加したいのですがどうすればよいでしょう? Cではreallocを使えばよいと思うのですが C++ではmallocではなくnewを使ったほうがよいと聞きました。 newした領域を再定義した場合(deleteせずに領域を追加) 先に領域に入れたデータは保証されるのでしょうか? 以下例文ソース*部分 以下例文のソース Test *a; a = new TEST[10]; int cnt; int i; for(i = 0;i<10;i++){  //ここでTESTの配列aに値を入れる } cnt = 12; if( cnt > 10 ){  //予想サイズを上回ったら足りない分のサイズの領域を確保し  //データを入れる  a = new[cnt];//*ここで領域を再確保したら元のa[0]~a[9]の         //データは確実に保持されるのか?         //または他に領域を確保する方法があるのか? } 上記例文ソースでは先にcntで領域を確保すれば良いようにみえますが やりたいことは 先に確保されている領域を広げて 先に入れてあったデータと、広げた領域に入れたデータを使いたい のです。 分かりにくい文章かもしれませんがよろしくお願いします。

  • C++ の new演算子について

    C++ の new演算子について質問です。 new演算子を用いてクラスのインスタンスを作ったときに、 クラスのメンバー関数内で使用される自動変数はメモリの何処に割り付けられますか? 以下の回答の内のいずれかと想定しています。 ・ヒープ領域 ・スタック領域 たとえば、以下のように、クラスTestClassが定義されていたとします。 class TestClass { int x; // int型(4byteとする) char y; // char型(1byte) long z; // long型(4byte) void play(short); } void main(void){ TestClass* pt = new a(); play(10); } void TestClass:: play(short n){ char a; long b; static c; for(int a = 0; a < 10; a++ ){ b = n * a; cout << b; } } main関数内で、インスタンスを作成した時点で ・TestClassのデータメンバx,y,z ⇒ ヒープ領域に確保(4+1+4 = 9byte。もしかしたらアライメント     の関係で もう少し大きく領域を確保するかも) ・play関数で使われる変数n,a,bの領域は何処に確保されるのでしょうか? 変数cは静的変数用領域に保存される? new演算子で作ったインスタンスはdelete演算子を使わないと消えないと勉強しました。(OSが消さない限り) つまり、上記ではmain関数を抜けても、変数x,y,z,n,a,bの実体は残ると考えてよいのでしょうか? そう考えると、n,a,bの実体はスタックではなく、ヒープ領域に確保する気がします、、 どうか、ご教授ください。

  • 領域の確保について

    callocやmallocで領域の確保が出来ると思いますが、領域が確保できなかったりする事があると思います。 char test[100000]; とか配列を宣言した場合も領域が確保されると思いますが、 これは確保する事が出来ない事とかはあるのでしょうか? また確保できなかった場合はどうなるのでしょうか? すいません、なんか勘違いしているかも知れませんが、宜しくお願いします。

  • c言語のメモリの確保について

    c言語で変数を宣言したり、領域を確保したりする場合に、メモリ上のこのアドレスに領域を確保する、といったように場所を指定することはできるのでしょうか?

  • mallocによる確保外の領域への参照

    構造体をmallocにより動的確保を行っていたのですが、例えば typedef struct _point{ int x, y; } point; point *pelem_point; pelem_point = (point *)malloc(sizeof(point)*5); このように、point型の構造体を5つ確保するとします。 しかし、 (pelem_point+100)->x = 1; (pelem_point+100)->y = 2; printf("%d\n", (pelem_point+100)->x); printf("%d\n", (pelem_point+100)->y); とやったら、確保していない100個先のところも構造体として利用できました。 なぜなのでしょうか。 自分の考えではこのようになりました。 mallocによりヒープ領域から適当な空いているメモリのアドレスが渡されるため、そこからはヒープ領域より先に、限りがあるまで進めてしまうために確保外のサイズにアクセスしても使えてしまっている。 また、mallocにより確保した場合は使用中のラベルがはられるため他に侵されることはないが、先の例のようにmallocによって確保してない場合はいくら使用できたとしても、空いているとコンピュータでは認識されるため、何かヒープ領域を使う場合に勝手に上書きされてしまう可能性がある。 しかし、この考えでも、なぜ確保外の領域が構造体のサイズ分ずつ区切られているのか納得いきません。 わかる方いましたらよろしくお願いします。