プログラム内のスタック解析


コンピュータの分野では、スタックは無視できない概念ですが、多くの人はコンピュータ専門の人でもスタックが実は2つのデータ構造であることを明確にしていません.
要点:
ヒープヒープ:順序が自由
スタック:先頭後出
スタックとスタックの違い
一、予備知識—プログラムのメモリ割り当て
c/C++でコンパイルされたプログラムが消費するメモリは、以下の部分に分けられます.
1、スタック領域(stack)-コンパイラによって自動的に割り当てられて解放され、関数のパラメータ値、ローカル変数の値などが格納されます.その動作は、データ構造内のスタックに似ています.
2、ヒープエリア(heap)—一般的にプログラマーによってリリースが割り当てられ、プログラマーがリリースしない場合、プログラム終了時にOSによって回収される可能性がある.データ構造のスタックとは異なることに注意してください.割り当て方はチェーンテーブルに似ています.ほほほ.
3、グローバル領域(静的領域)-、グローバル変数と静的変数の記憶はブロックにあり、初期化されたグローバル変数と静的変数はブロック領域にあり、初期化されていないグローバル変数と初期化されていない静的変数は隣接する別のブロック領域にある.-プログラム終了後にシステム解放
4、文字定数領域-定数文字列はここにあります.プログラム終了後にシステムから解放
5、プログラムコード領域-関数体のバイナリコードを保存する.
二、例プログラム
これは先輩が書いたもので、とても詳しいです.
//main.cpp
int a = 0; //      
char *p1; //       
main()
{
int b; // 
char s[] = "abc"; // 
char *p2; // 
char *p3 = "123456"; //123456/0    ,p3   。
static int c =0; //  (  )    
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//     10 20         。
strcpy(p1, "123456"); //123456/0     ,         p3    "123456"       。
}

二、スタックとスタックの理論知識
2.1申請方式
stack:
システムによって自動的に割り当てられます.例えば、関数内の局所変数int bを宣言する.システムは自動的にスタックの中でbのために空間を開きます
heap:
プログラマーが自分で申請し、サイズを指定し、cでmalloc関数を指定する必要があります.
例えばp 1=(char*)malloc(10);
C++でnew演算子を使う
例えばp 2=(char*)malloc(10);
ただし、p 1、p 2自体はスタック内にあることに注意してください.
2.2申請後のシステムの応答
スタック:スタックの残りの領域が申請された領域より大きい場合、システムはプログラムにメモリを提供します.そうしないと、例外プロンプトスタックがオーバーフローします.
ヒープ:まず、オペレーティングシステムに空きメモリアドレスを記録するチェーンテーブルがあることを知っておく必要があります.システムがプログラムの申請を受け取ったとき、
チェーンテーブルを巡回し、最初の空間が申請された空間より大きいスタックノードを探し、そのノードを空きノードチェーンテーブルから削除し、そのノードの空間をプログラムに割り当てます.また、ほとんどのシステムでは、このメモリ空間の最初のアドレスに今回の割り当てのサイズが記録されます.これにより、コードのdelete文がメモリ空間を正しく解放することができます.また,見つかったスタックポイントの大きさが申請の大きさに等しいとは限らないため,余分な部分を自動的に空きチェーンテーブルに再配置する. 
2.3申請サイズの制限
スタック:Windowsの下で、スタックは低アドレスに拡張されたデータ構造で、連続したメモリの領域です.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、WINDOWSではスタックの大きさは2 M(1 Mということもあり、つまり1つのコンパイル時に決定される定数)であり、申請された空間がスタックの残りの空間を超えるとoverflowが提示される.したがって、スタックから得られる空間は小さい.
ヒープ:ヒープは高アドレスに拡張されたデータ構造で、不連続なメモリ領域です.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
2.4出願効率の比較
スタックはシステムによって自動的に割り当てられ、速度が速い.しかし、プログラマーはコントロールできません.
スタックはnewで割り当てるメモリで、一般的に速度が遅く、メモリの破片が発生しやすいが、最も使いやすい.
また、WINDOWSでは、VirtualAllocでメモリを割り当てるのが一番です.彼はスタックではなく、スタックではなく、プロセスのアドレス空間に直接高速メモリを残すのではなく、最も使いにくいです.しかし、速度が速く、最も柔軟です.
2.5スタックおよびスタック内のストレージ
スタック:関数呼び出し時に、最初にスタックに入ったのは主関数の次の命令(関数呼び出し文の次の実行可能文)のアドレスで、それから関数の各パラメータで、ほとんどのCコンパイラでは、パラメータは右から左へスタックに入って、それから関数数の中の局所変数です.静的変数はスタックに入らないことに注意してください.
今回の関数呼び出しが終了すると、ローカル変数は先にスタックを出て、それからパラメータで、最後にスタックトップポインタは最も最初に保存されたアドレス、つまりメイン関数の次の命令を指し、プログラムはこの点から実行を継続します.
ヒープ:通常、ヒープのヘッダにヒープのサイズを1バイトで格納します.スタックの具体的な内容はプログラマーが手配します.
2.6アクセス効率の比較
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbはコンパイル時に確定した.
しかしながら、以降のアクセスでは、スタック上の配列はポインタが指す文字列(例えばスタック)よりも速い.
例:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}

対応するアセンブリコード
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
1つ目は、読み出し時に文字列の要素をレジスタclに直接読み出し、2つ目はポインタ値をedxに読み出し、edxに基づいて文字を読み出すのは明らかに遅い. 
2.7まとめ
スタックとスタックの違いは、次のような比喩で見ることができます.
宿を使うのは私たちがレストランで食事をするのと同じで、料理を注文して(申請を出して)、お金を払って、食べて(使用して)、満腹になったら行って、野菜を切って、料理を洗うなどの準備と茶碗を洗って、鍋を洗うなどの掃除の仕事を気にする必要はありません.彼のメリットは速いですが、自由度は小さいです.
山を使うのは自分で好きな料理を作るようなもので、面倒ですが、自分の好みに合っていて、自由度が高いです.
スタックとスタックの違いは主に次のとおりです.
オペレーティングシステムのスタックとスタックは、上記のように、多くは言いません.
また、データ構造のスタックとスタックもあり、これらは異なる概念です.ここでのスタックは、実際には(スタックの性質を満たす)優先キューのデータ構造を指し、1番目の要素が最も優先権を持っている.スタックは実際には先進的な後出の性質を満たす数学やデータ構造である.
スタック、スタックという言い方はつながっているが、彼らには大きな違いがあり、つながっているのは歴史のせいだ.