[解決済み】brk()システムコールは何をするのですか?
質問
Linuxのプログラマーズマニュアルによると。
brk()およびsbrk()は、プログラムのブレークの位置を変更します。 は、プロセスのデータ・セグメントの終わりを定義します。
こっちのデータセグメントってどういう意味なんだろう?データセグメントだけなのか、データ、BSS、ヒープを合わせたものなのか?
wikiによると データセグメント :
データ、BSS、ヒープ領域を総称してデータセグメントと呼ぶことがあります。
データセグメントだけのサイズを変更する理由はないと思います。データであれば ビーエスエス とヒープを一緒にすると、ヒープがより多くのスペースを得ることになるので、理にかなっています。
そこで、2つ目の質問をさせていただきます。私がこれまでに読んだすべての記事で、著者はヒープが上向きに成長し、スタックが下向きに成長すると言っています。しかし、彼らが説明していないのは、ヒープがヒープとスタックの間のすべての空間を占めたときに何が起こるか、ということです。
解決方法は?
投稿された図では、"break"-で操作されるアドレスが表示されています。
brk
と
sbrk
-はヒープ上部の点線である。
<イグ
あなたが読んだドキュメントでは、これが "データセグメントの終わりと説明されています。
mmap
プログラム開始前にカーネルは、quot;text" と "data" ブロックをアドレスゼロから始まる RAM にロードし(実際にはアドレスゼロより少し上で、純粋に NULL ポインタが何も指していないように)、ブレークアドレスをデータセグメントの終端に設定するのです。 最初の
malloc
を使用することになります。
sbrk
を使用して、ブレークアップを移動し、ヒープを作成します。
間に
を使用すると、図に示すように、データセグメントの先頭と新しい高いブレークアドレスが表示されます。
malloc
は、必要に応じてヒープを大きくするために使用されます。
一方、スタックはメモリの最上位から始まり、下に伸びていく。 スタックを大きくするために明示的なシステムコールを必要としません。スタックは、持てるだけの RAM が割り当てられた状態からスタートするか(これが従来のアプローチでした)、スタックの下に予約アドレスの領域があり、そこに書き込もうとするとカーネルが自動的に RAM を確保します(これが現代のアプローチです)。 いずれにせよ、アドレス空間の最下部にスタックに使用できる "guard"領域がある場合とない場合があります。 この領域が存在する場合(最近のシステムはすべてそうなっています)、それは永久にアンマップされます。 どちらかというと スタックやヒープがそこに成長しようとすると、セグメンテーションフォールトが発生します。 スタックがヒープの中に入り込んだり、ヒープがスタックの中に入り込んだり、どちらにしてもお互いのデータを上書きすることになり、プログラムがクラッシュしてしまいます。 もし、あなたがとても幸運なら、すぐにクラッシュするでしょう。
この図の512GBという数字がどこから来ているのか、よくわからないのですが。 これは64ビットの仮想アドレス空間を意味しており、そこにある非常にシンプルなメモリーマップと矛盾しています。 本当の64ビットアドレス空間は、このようなものです。
Legend: t: text, d: data, b: BSS
また、この図は、どのOSがどのように動作しているかを正確に示すものではありません(この図を描いた後、Linuxでは実行ファイルを私が思っていたよりもずっとアドレスゼロに近づけており、共有ライブラリも驚くほど高いアドレスに置いていることがわかりました)。この図の黒い領域はマッピングされていないもので、アクセスすると即座にセグメンテーションフォールトが発生します。 巨大 グレーの部分と比較すると 薄い灰色の領域は、プログラムとその共有ライブラリ(共有ライブラリは何十個もある)で、それぞれには 独立した テキストとデータのセグメント(および "bss" セグメントはグローバルデータも含みますが、実行ファイルやディスク上のライブラリで領域を占有するのではなく、オールビットゼロに初期化されます)です。 ヒープはもはや実行ファイルのデータセグメントと必ずしも連続しているわけではありません -- 私はそのように描きましたが、少なくともLinuxではそうではないようです。 スタックはもはや仮想アドレス空間の最上部に固定されておらず、ヒープとスタックの間の距離は非常に大きいので、それを越えることを心配する必要はないでしょう。
ブレークがヒープの上限であることに変わりはありません。 しかし、私が示さなかったのは、どこかの黒い場所で、何十もの独立したメモリ割り当てが
mmap
の代わりに
brk
. (OSはこれらを
brk
の領域で、衝突しないようにします)。
関連
-
[解決済み】変数の警告が設定されているが使用されていない
-
[解決済み】 「配列のイニシャライザーはイニシャライザーリストまたは文字列リテラルでなければなりません」と表示されるのですが?
-
[解決済み] シェルで、「2>&1」はどういう意味ですか?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] time(1) の出力における 'real', 'user' および 'sys' はどのような意味ですか?
-
[解決済み] C++でextern "C "を使用した場合の効果は?
-
[解決済み] Bashでファイルの中身をループする
-
[解決済み] C言語のコードで「:-!」とは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「ポインタから異なるサイズの整数へのキャスト」エラーが発生するのはなぜですか?
-
[解決済み] c - 初期化がキャストなしでポインタから整数を作る、さらに2つのコンパイラーエラー
-
[解決済み】初期化がキャストなしで整数からポインタを作成 - C言語
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み】C言語でint64_t型を表示する方法
-
[解決済み】argv[]をint型として取得するには?
-
[解決済み】Makefile:1: ***セパレータがありません。停止します。
-
[解決済み】makefile:4。*** missing separator. 停止する
-
[解決済み] x86アセンブリでレジスタに使用されるpush/pop命令の機能は何ですか?
-
[解決済み] POSIX」の意味を教えてください。