前回、C 言語のメモリの 4 つの領域に関する関連知識を共有しましたが、ここで、スタックの成長方向と配列の成長方向とは何ですか?
ここで検証を行うことができます.まず上向きのメモリアドレスが大きいと仮定して,まずスタック上に2つのスペースを開けます.最初に要求されたメモリアドレスが小さい場合,スタックの開く方向が上向きであることを意味します.スタックは先入れ後出しなので、最初に適用されたメモリアドレスが大きいほど、下向きに開いていることを意味します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//堆
char *getMem(int num)
{
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char)*num);
if (p1 == NULL)
{
return NULL;
}
return p1;
}
//栈
char *getMem2()
{
char buf[64] = { 0 };
strcpy(buf, "123456789");
return buf;
}
int main(int argc, char *argv[])
{
//char *tmp = NULL;
//tmp = getMem(10);
//if (tmp == NULL)
//{
// return -1;
//}
//strcpy(tmp, "1111222");//向tmp所指向的内存空间中copy数据
//
//printf("heap:getMem:%s\n", tmp);
//tmp = getMem2();
//printf("stack:getMem:%s\n", tmp);
int a;
int b;
//不管栈的开口向上还是向下,buf的内存地址buf+1永远是向下
char buf[128];
printf("&a:%d,&b:%d\n", &a, &b);
system("pause");
return 0;
}
b のアドレスが a のアドレスよりも小さいことがわかります。これは、コンパイラのスタック オープンが下向きであることを証明しています。
ただし、配列の場合、buf+1 のアドレスは buf のアドレスより大きいため、配列の成長方向はスタックの成長方向とは異なります。
関数呼び出しのモデルについて話しましょう。
メイン関数が他の関数を呼び出すと、割り込みのようなメカニズムが現れることがわかります.最初にサブ関数のパラメーターがスタックにプッシュされ、次にサブ関数が最初に実行され、次にスタック メモリが割り当てられます。サブ関数によってデストラクタによって破棄されます。
ここで、サブ関数で割り当てられたヒープとスタックメモリが fa と fb で使用できる場合に注意してください。
fa によってスタック上に確保されたメモリが main 関数では使用できないが、fb 関数では使用できる場合は、fa 関数の実行後に fa のスタック空間のメモリが解放されるため、fb 関数では使用できません。ただし、fb 関数で割り当てられたヒープ領域など、ヒープ領域に割り当てられた領域が main 関数と fa 関数の両方で使用できる場合は、ヒープ メモリは関数の実行後に解放されます。プログラムは終了します。