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

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

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

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Q&A

解決済

5回答

8227閲覧

スタック領域は動的か静的か

退会済みユーザー

退会済みユーザー

総合スコア0

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

2グッド

3クリップ

投稿2018/10/10 02:35

編集2018/10/10 02:59

スタックとヒープについて調べていました。

メモリを以下のように4つの領域に分けられることを知りました。

  • プログラム領域
  • 静的領域
  • ヒープ領域
  • スタック領域

【参考】メモリの 4 領域
どこを見てそう思ったのか忘れてしまいましたが、上2つが「静的」、下2つが「動的」なメモリ領域だと認識していました。

また、以下のような説明を見つけました。

  • コンパイル時に決まるものが「静的」
  • 実行中に変化するものが「動的」

しかし、スタックとヒープの解説をしている記事に、

  • スタックはコンパイル、リンクする時点でサイズは決まっている

【参考】ヒープとスタック | 学校では教えてくれないこと | [技術コラム集]組込みの門 | ユークエスト株式会社

と、ありました。
この時点で解釈に矛盾が生じるのですが、どこが間違っていますでしょうか。
どなたかご存知の方がいらっしゃればご教示願えませんでしょうか
よろしくおねがいします。

atled, atata0319👍を押しています

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

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

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

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

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

sazi

2018/10/10 02:48

質問の根拠になっている記事の情報を質問に追記された方がいいですよ。
guest

回答5

0

こんにちは。

スタックはコンパイル、リンクする時点でサイズは決まっている

この「サイズ」は「最大サイズ」です。実際に使っているサイズはプログラムの実行中に増減します。
なので「動的」なのですよ。

投稿2018/10/10 04:44

Chironian

総合スコア23272

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

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

sazi

2018/10/10 04:51

ぶら下がり質問失礼します。 スタックの最大サイズってコンパイル&リンク時点で決まるのですか? 実行環境とコンパイル環境のリソースの違いは気にされないって事でしょうか?
sazi

2018/10/10 05:00

そもそもスタックって変数だったりCALL時の戻りポインタなどを格納すると思うのですが、動的な変数や再帰などで動的に変化するものなのに、コンパイル&リンク時点で最大サイズってどうやって求められるんでしょう。
otn

2018/10/10 05:51

スタックサイズの指定方法は、OSに依るかと。 古い(?)OSだとリンク時に決めます。 質問者が参照したのは、組み込み系の会社のサイトのようなので、リンク時に決まるというのは正しそうに思います(組み込みが全部そうと言う事もないでしょうが)。
sazi

2018/10/10 06:08

サイズが動的に決まるというような回答に見て取れました。 リンク時にスタックサイズを指定する事も可能であったりしますが、 「プログラムの作りによってスタック領域の最大サイズが変動するということは無い」 という事で認識は合っていますでしょうか。
otn

2018/10/10 06:17

少なくともLinuxには、setrlimit というシステムコールがあり、自プロセスのスタックサイズを変更できるようです。拡大できるのかどうかは分かりません。
sazi

2018/10/10 06:34

質問がまずかったですね。「プログラムの作り」ではなく「プログラムソース」とするべきでした。 ありがとうございます。
Chironian

2018/10/10 06:53

saziさん > 実行環境とコンパイル環境のリソースの違いは気にされないって事でしょうか? 最大サイズは実割当サイズではないので、相違が有っても問題ないです。 > 動的な変数や再帰などで動的に変化するものなのに、コンパイル&リンク時点で最大サイズってどうやって求められるんでしょう。 1つのプロセスは1つのメモリ空間(実メモリではなくアドレス空間)と複数のスレッドを持ちます。 1つのスレッドは1つのスタックを持ち、1つのスタックには連続したメモリ空間が割り当てられます。 つまり、1つのプロセスに属する複数のスタックは1つのメモリ空間を分割して使用します。 ですので、スタックとスタックの間をどの程度開けて割り当てるのか決める必要があります。これがスタックの最大サイズです。 決めることができる/できないの問題ではなく、有限の資源(この場合は実メモリではなくアドレス空間)をどのように配分するのか決めなければ行けないという話です。 スタックの最大サイズをいつ決めるのかという議論はあると思います。アドレス空間の広さはCPUとOSのアーキテクチャが決まれば決まります。これらが決まらないとプログラムをビルドできませんので、ビルド時にスタックの最大サイズを決定しても問題ないと思います。 しかし、起動前までにスタックの最大サイズを決定できれば十分ですから、ビルド時に決定せずシステム側で決定することも可能と思います。otnさんによるとlinuxはそうなっているようですね。これは知らなかったです。
sazi

2018/10/10 07:11

元々は質問者さんがリンク先を誤った解釈(私はそう回答しています)をされたものを、正として回答されているので、この回答を元にリンク先を読み直しても混乱すると思いコメントしました。 ですが、ここまで有用な情報がコメントされたので理解していただけるものと思います。 ありがとうございました。
guest

0

あなたの言う動的、というのはどういうことでしょうか。
まずはそこらへんをはっきりさせる必要があります

サイズを動的に操作するのが動的、と定義するのであれば、スタックは静的なんでしょう。
しかし、内容を変化させるエリアを動的、とするなら、ヒープもスタックも動的、となります。

どっちでしょうか。

#まあ、普通はコード、CONSTは内容が変わらず(ROM)
#ヒープとスタックは、内容を変化させる、変化することができる(RAM)
#と、区別するもんですが

投稿2018/10/10 07:25

編集2018/10/10 13:42
y_waiwai

総合スコア87774

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

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

退会済みユーザー

退会済みユーザー

2018/10/10 23:26

回答有り難うございます。 僕の解釈では後者の「内容が変化する」のを「動的」だとするものでした。
y_waiwai

2018/10/10 23:30

なら別にその確保サイズについてはどーでもいいのでは。 って、ヒープエリアもサイズは決まってるっちゃー決まってますわな。その中で確保したり開放したりしてるだけで
退会済みユーザー

退会済みユーザー

2018/10/10 23:36

あ、たしかに質問時には「サイズ」と「内容」がごっちゃになっていました。 https://he-s3.s3.amazonaws.com/media/uploads/383f472.png ↑この画像を見ると、 コンパイル時に、一番大きな長方形と、静的な下3つの長方形は「サイズ」が決まっているので、残りの「スタック&ヒープ」の部分も「サイズは」決まる。 しかし、「内容」は実行時に変化するので、「動的」という理解であっていますでしょうか。
y_waiwai

2018/10/11 00:04

なんのためにその区別をするのかはっきりさせよう。 組み込み用途では、前2つをROM(内容は変更できない)に書き込み、 あと2つはRAM(書き換えできるメモリ)に割り当てるということをしますな。
guest

0

ベストアンサー

コンパイル時に決まるものが「静的」
実行中に変化するものが「動的」

ヒープとスタックは、コンパイル(&リンク)時に決まっているのになぜ、動的なのか? という疑問ですね。
確かに、ヒープ領域とスタック領域はコンパイル時に決まっています(OSによって若干の例外あり?)が、ヒープ領域とスタック領域に置かれるデータは、動的に配置されるという事です。

通常のプログラム(C とかのコンパイル言語を想定)で、「スタック領域の何番地」とか、「ヒープ領域の何番地」という指定をする事はありません。
data1 とか、text1 とかの変数を使用しますが、その変数が動的という事です。

C

1int ExtData; 2 3void test1() 4{ 5 int data1; 6 char text1[50]; 7 // ..... 8}

と言うCプログラムがあった場合、(通常) data1 と text1 は、スタック領域にデータが置かれ、そのアドレスは、関数 test1 が呼び出されるタイミングで、アドレスが異なります。 (こちらが動的) ヒープも同様。
これに対し、 関数の外側で宣言されている ExtData は、コンパイル(リンク)時に決まったアドレス(多分、BSS内)に置かれます。 (こちらが静的)
また、プログラム(コード)もコンパイル(リンク)時に置かれるアドレスが決まるので、静的となります。

コンパイル(リンク)時に置かれるアドレスが決まる → 静的
実行時に置かれるアドレスが決まる → 動的

で良いかと思います。

[追記]見出しの「スタック領域は動的か静的か」についての回答は、
--> スタック領域は、静的に確保される。スタック領域に置かれるデータは、動的に配置される。
ですね。


歴史的には、相対アドレスで動き、実行時にアドレスが決まるコードとかありますが、最近は主流じゃないですね。 また、インタープリタなども違うとかありますが。
それと、最近は仮想記憶で、以前ほどメモリ割り当ては厳しくない気もします。
問題なのは、参考にされたページの見出しにあるようにメモリとかが厳しい組込み系かと思います。

投稿2018/10/10 13:39

編集2018/10/10 13:48
pepperleaf

総合スコア6383

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

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

退会済みユーザー

退会済みユーザー

2018/10/10 23:43

回答有り難うございます。 「スタック&ヒープ」は、 領域、サイズはコンパイル時に決まり、(←ここじゃなくて) 中身であるデータは、実行時に決まる.(←こっちが動的) ということでしょうか。 少し質問の趣旨とはずれますが、「コンパイル時にアドレスが決まる」というのがよくわかりません。 僕は普段はスクリプト言語を触っているので大きな誤解があったかもしれません。というのも、例えばCで書かれたプログラムを共有するときは、以下のいずれでも良いかと思っていました。 - Cのコードを共有し、実際に使うマシン上でコンパイルする - コンパイルされたあとの実行ファイルを共有する ですが、「コンパイル時にアドレスが決まる」という部分を見ると、前者出ないといけないのかなと思いました。 初歩的な質問ですみません。 よろしくおねがいします。
pepperleaf

2018/10/11 12:04 編集

> 中身であるデータは、実行時に決まる.(←こっちが動的) 動的の意味はこっちでしょう。 通常のコンパイル済みプログラムは、ファイル形式にお約束があり、プログラムをメモリ上に置く(読込む)場合に、どう配置するか決まっています。(OS/CPUに依存) コンパイラは、その形式に合わせて実行プログラムを作成します。 「コンパイル時にアドレスが決まる」とは、メモリ上のどこに置くか決まっている事を示します。(従って、コンパイルを行うのは、実際に使うマシンである必要は無い) これに対し、スタックに置かれるデータは、スタックの先頭から、順次、使われるので、プログラムの実行次第で、どのアドレスかは決まっていません。(同じになる事も多いが) スクリプト言語は、スクリプト言語を読み込んで実行するプログラムが動いています。それに対し、コンパイル言語は、コンパイル結果をメモリ上に置き、CPUが直接、読み込んで実行します。(という事になっている。また、仮想計算機なんてのもありますが、ちょっと置きます) 以上は、PC等で、プログラムを(書換え可能な)メモリに置く場合で、組込み等で、書き換え不可のメモリに置く場合はプログラムを読込むと言う表現は正しくないですが、イメージとしては近いです。
guest

0

参考にされた記事(ヒープとスタック)では、

プログラムやOSをコンパイル(リンク)した時点でセクションのアドレスとサイズが決まっていて、動作中にセクションのアドレスやサイズが変わることは無いんだ。これに対して、『ヒープ領域』や『スタック領域』は、プログラム中で一時的に使用するメモリのことで、普通はRAM上のどこかのセクションの一部に属することになる。

とあります。
「アドレスとサイズが決まっている」のはプログラムの事です。
ここで言うサイズはプログラムコードのサイズで、アドレスとはプログラムコード中のプログラムセクションの相対アドレスの事です。

投稿2018/10/10 03:24

編集2018/10/10 03:36
sazi

総合スコア25184

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

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

0

矛盾は生じていないですよ。

スタックはコンパイル、リンクする時点でサイズは決まっている

「サイズは」決まっていると明確に書いてあります。内容は動的に変わります。

投稿2018/10/10 02:47

mather

総合スコア6753

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

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

sazi

2018/10/10 02:53 編集

プログラムによって、サイズが決まっているなら、スタックオーバーフローがなぜ発生するのでしょう?
mather

2018/10/10 02:54

サイズが決まっているからスタックオーバーフローが発生すると思うのですが…。
sazi

2018/10/10 02:59

スタック領域のサイズはプログラムによるものではなく、OSや実行オプションによって決まるものだと思うのですが・・・
mather

2018/10/10 03:07

あ、そっちのツッコミですね。それは正しいと思います。僕は「サイズが決まっているからスタックオーバーフローが発生する」という意図で書きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問