C言語での関数呼び出しのモデル

前回、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 関数の両方で使用できる場合は、ヒープ メモリは関数の実行後に解放されます。プログラムは終了します。 

おすすめ

転載: blog.csdn.net/qq_45526401/article/details/127349174