[C]メモリ構造

3212 ワード

C言語メモリ構造:方法:
  • 0.コードセグメント:関数バイナリコードを格納する領域;
  • 1.RO DATA読取り専用データセグメント(静的領域):ローカルでもグローバルでも変化しない定数を格納する.
  • 2.RW DATA読み書きデータセグメント(静的領域):変更可能なグローバル変数(定義時に直接初期化することを前提とする)を格納するか、staticで修飾されたローカル変数(初期化も必要):staticは現在の{}プログラムコードセグメントでのみ有効である.
  • 3.BBS未初期化データ領域(静的領域):グローバルとローカルの違いに分けてここに置かれ、初期化後のみ対応するスタックまたはRW,RO DATA、(定義時には初期化を除く)静的領域の未初期化の変数がここに格納され、未初期化の変数が格納されるのは普段はないが、プログラム実行時に動的に生成する(従って通常exeにはこれを含まないサイズ)、コンパイラがサイズを明確に指定する必要がある(初期化されていないため).
  • 4.関数内部のローカル変数は、staticやconstで説明する必要はなく、スタックに配置され、スタック上のデータは自動的に解放されます.主なストレージ:ローカル変数、パラメータ、戻り値、変数空間は関数の開始前に開き、終了後に回収される.
  • 5.アプリケーション:const char *ptrConst = "fdsfadf";文字列定数はRO DATAに、const修飾を加えたポインタは、グローバルなため、静的領域(RO DATA)にあるに違いないが、ptrConstが指す内容は変更できず、自身が指すアドレスは可変である.したがってptrConstはRW DATA(ここではグローバルな状況を指し、局所的に定義されている場合、ptrConstはスタックの上に格納され、const char const *ptrConst = "fdsfadf";は両方ともRO DATAに格納される;const char a[] = "fsdfds";配列はポインタとは異なり、両方ともRO DATAに格納され、配列は完全に「fsdfsds」に等価であると考えられる変えられないconstポインタ:const char *p = XXX p可変、*pはconst;const (char *)p = XXX pはconstであり、*pは可変である.const char * const p = xxx最强の拘束は、すべてconstつまりconstがそれに近いので、どれがconstですが、直接后ろに置くことができます:char const*p=XXX//p可変、*pはconst(char)const p=XXX//pはconstで、p可変char*const p=XXXX//pはconstで、p可変char const*const p=xxx//最强の拘束は、すべてconstが番号に沿って线を引いています.constが左側にある場合、constはポインタが指す変数を修飾するために使用され、すなわちポインタが定数を指す.constが右側にある場合、constは修飾ポインタ自体、すなわちポインタ自体が定数である.このルールに基づいて、上記の声明の実際の意味を見ることができ、きっと一目瞭然だと信じています.注意:1 constで定義されたグローバル変数は、保存するには、関数もconstであることを示す必要があります.そうしないと、外部から読み取ることができず、参照するしかありません.②読取り専用データ定義の場合、通常は完全な初期化を行います.そうしないと、RO DATAの
  • にあるため、余分な初期化されていない空間も適用できません.
  • 6.スタックとスタック:柔軟でなければ柔軟ではありません.このように効率は相対的に高いサイズになります.スタックは固定サイズのメモリ空間で、超えるとover flowが提示され、スタックはチェーンテーブルで、メモリサイズと関係があります.効率:スタックはもっと柔軟で、相対効率はずっと低くて、スタックは比較的にデッドボードで、しかし効率が高い(スタックはオペレーティングシステムによって維持されて、スタックはプログラムによって維持されている)スタックは機械システムが提供するデータ構造で、コンピュータは底層でスタックに対してサポートを提供します:専門のレジスタを割り当ててスタックのアドレスを保存して、スタックを押し出すのはすべて専門の命令が実行して、これによりスタックの効率が比較的高いことが決定される.スタックはC/C++関数ライブラリで提供され、そのメカニズムは複雑です.例えば、メモリを割り当てるために、ライブラリ関数は一定のアルゴリズム(具体的なアルゴリズムはデータ構造/オペレーティングシステムを参照できます)に従って、スタックメモリの中で利用可能な十分なサイズの空間を検索します.十分なサイズの空間がなければ(メモリの破片が多すぎるためかもしれません)、システム機能を呼び出してプログラムデータセグメントのメモリ領域を増やすことができ、十分なサイズのメモリに分けて返す機会があります.明らかに、スタックの効率はスタックよりずっと低い.

  • 注意:
  • (1)スタック:char*s 1="hellow tigerjibo";コンパイルで決定された(2)スタック:char s 1[]="hellow tigerjibo";実行時に付与されます.ポインタを使用するよりも配列を使用する方が高速で、ポインタは最下位アセンブリでedxレジスタで中継する必要があり、配列はスタックで読み出す必要があります.同じ読み取り専用データ領域のデータは、ポインタよりも配列で取得するのが速い.
  • (2)スタック:関数呼び出し時に、最初のスタックの主関数の後の次の文のアドレス、それから関数の各パラメータ、パラメータは右から左へスタックに入って、それから関数の中の局所変数です.注意:静的変数はスタックに入れません.今回の関数呼び出しが終了すると、局所変数は先にスタックを出て、それからパラメータで、最後にスタックトップポインタは最も最初に保存されたアドレス、つまり主関数の次の命令を指して、プログラムはこの点から実行し続けます.
  • (3)スタック:一般的にスタックのヘッダにスタックのサイズを1バイトで格納し、後で直接コンテンツを格納し、アドレスを覚えれば使用できるので、柔軟です.スタックはオペレーティングシステムが空きメモリ空間アドレスを格納するチェーンテーブルであり、申請するたびにチェーンテーブルから空間を探し出す」=申請サイズのノードは、プログラム用(多く出た部分はチェーンテーブルの上に新しいノードを生成する)に解放され、一般的に空間の最初の部分は今回割り当てられたサイズを格納し、freeを便利にする際に空間解放を行う.リリース後、再びノードとしてチェーンテーブルに格納します.説明:スタックにとって、頻繁なnew/deleteはメモリ空間の不連続をもたらし、大量の破片をもたらし、プログラムの効率を低下させるに違いない.スタックにとって、この問題は存在しません.