メモリはデータ、ヒープ、スタック、コードの4つのセグメントに分けられます。グローバル変数、スタティック変数、定数データ型、ローカル変数(関数内で定義および宣言)、変数(メイン関数内)、ポインタそして、動的に割り当てられた空間(mallocとcallocを使って)はメモリに格納されますか?
それらは次のように割り当てられると思います。
char *arr
、int *arr
)-------> heapこれらの変数については、Cの観点からのみ言及しています。
私はCに慣れていないので私が間違っているなら私を訂正してください.
あなたはこれらの権利のいくつかを手に入れました、しかし質問を書いた人は誰でも少なくとも1つの質問にあなたをだましました:
main
関数で宣言および定義された変数-----> char *arr
、int *arr
)-------> static
ポインタを宣言できます。この場合、ポインタ自体がデータセグメントに入ります。malloc
、calloc
、realloc
を使用)--------> 「スタック」が正式に「自動ストレージクラス」と呼ばれることは言及する価値があります。
それらのメモリセグメントについて知ることに興味があるかもしれないそれらの将来の訪問者のために、私はCの5つのメモリセグメントについて重要なポイントを書いています:
いくらか上がる:
Cの5つのメモリセグメント:
printf("Hello, world")
を実行すると、文字列 "Hello、world"がcode/textセグメントに作成されます。これはLinux OSのsize
コマンドで確認できます。データセグメントは下の2つの部分に分割され、通常はヒープ領域の下、または一部の実装ではスタックの上にありますが、データセグメントはヒープ領域とスタック領域の間にはありません。
int globalVar;
または静的ローカル変数static int localStatic;
は、未初期化データセグメントに格納されます。0
またはNULL
として初期化すると、それでも初期化されていないデータセグメントまたはbssになります。int globalVar = 1;
または静的ローカル変数static int localStatic = 1;
は、初期化されたデータセグメントに格納されます。malloc
、calloc
、またはrealloc
メソッドを使用して行われます。int* prt = malloc(sizeof(int) * 2)
の場合、8バイトがヒープに割り当てられ、その場所のメモリアドレスが返されてptr
変数に格納されます。 ptr
変数は、宣言または使用方法に応じて、スタックまたはデータセグメントのどちらかにあります。あなたの間違った文章を修正
constant data types -----> code //wrong
ローカル定数変数-----> stack
初期化されたグローバル定数変数----->データセグメント
未初期化グローバル定数変数-----> bss
variables declared and defined in main function -----> heap //wrong
main関数で宣言および定義された変数-----> stack
pointers(ex:char *arr,int *arr) -------> heap //wrong
dynamically allocated space(using malloc,calloc) --------> stack //wrong
ポインタ(例:char * arr、int * arr)------->ポインタ変数のサイズはスタックになります。
Nバイトのメモリーを(malloc
またはcalloc
を使用して)動的に割り当ててから、それを指すようにポインター変数を作成するとします。 n
バイトのメモリがヒープにあり、ポインタ変数はn
バイトのメモリチャンクの開始ポインタを格納するためのスタックになる4バイト(64ビットマシンの場合8バイト)を必要とします。
注:ポインタ変数は任意のセグメントのメモリを指すことができます。
int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal
//which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}
動的割り当て領域(malloc、callocを使用)-------->ヒープ
一般的なデスクトップアーキテクチャは、プロセスの仮想メモリをいくつかに分割しますセグメント:
テキストセグメント:実行可能コードを含みます。命令ポインタはこの範囲の値を取ります。
データセグメント:大域変数(すなわち静的リンケージを有するオブジェクト)を含む。読み取り専用データ(文字列定数など)と未初期化データ( "BSS")に分割されています。
スタックセグメント:プログラム用の動的メモリ、すなわちフリーストア(「ヒープ」)およびすべてのスレッド用のローカルスタックフレームを含む。伝統的に、CスタックとCヒープは反対側からスタックセグメントに成長していましたが、安全性が高すぎるため慣習は中止されたと思います。
Cプログラムは通常、静的記憶期間を持つオブジェクトをデータセグメントに、動的に割り当てられたオブジェクトをフリーストアに、自動オブジェクトをそれが存在するスレッドの呼び出しスタックに入れます。
古いx86リアルモードや組み込みデバイスなどの他のプラットフォームでは、明らかに事情が大きく異なります。
これらの変数はCの観点からのみ参照しています。
C言語の観点からすると、重要なのは範囲、範囲、リンケージ、およびアクセスだけです。アイテムが異なるメモリセグメントにどのようにマッピングされるかは個々の実装次第であり、それは異なります。言語標準はメモリセグメントについては話しませんまったく。ほとんどの現代建築はほとんど同じように機能します。ブロックスコープ変数と関数引数はスタックから割り当てられ、ファイルスコープと静的変数はデータまたはコードセグメントから割り当てられ、動的メモリはヒープから割り当てられ、一部の定数データは読み取り専用セグメントに格納されます。など.
ポインタ(例:char * arr、int * arr)------->ヒープ
いいえ、それらはスタック上にあってもデータ・セグメント内にあってもかまいません。彼らはどこでも指すことができます。
ストレージについて留意する必要があることの1つは、 as ifルール です。コンパイラは変数を特定の場所に置く必要はありません-代わりに、コンパイルされたプログラムが動作する限り、好きな場所に変数を置くことができますas ifそのルールに。これはすべてのストレージに適用されますdurations。例えば:
42
があるが、404
の兆候がないことを確認します。const
または実質的にconst
である変数は、メモリ内にある必要はありません。 例 -コンパイラーは、foo
が実質的にconst
であることを証明し、その使用をコードにインライン化できます。 bar
には外部リンケージがあり、コンパイラは現在のモジュールの外部で変更されないことを証明できないため、インライン化されません。malloc
で割り当てられたオブジェクトは、ヒープから割り当てられたメモリに存在する必要はありません! 例 -コードにmalloc
の呼び出しがなく、値42もメモリに保存されず、レジスタに保持されていることに注意してください!malloc
によって割り当てられたオブジェクトと参照は、free
でオブジェクトの割り当てを解除せずに失われますneed notメモリのリーク...malloc
によって割り当てられたオブジェクトは、ヒープ内にある必要はありません下 Unixenのプログラムブレーク(sbrk(0)
)...