c语言之函数调用的模型

上次分享c语言中内存四区的相关知识,这边再补充一下栈的生长方向和数组的生长方向是什么样的?

这边可以做个验证,可以先假定往上的内存地址是较大的,先在栈上开辟两块空间,如果先申请的内存地址较小的话就说明栈的开口方向是向上的,因为栈是先进后出的,如果先申请的的内存地址较大的话就说明开口是向下的。

#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在栈空间中的内存就被释放了,所以在main函数中无法使用,但是如果过是在堆区里面分配的空间,例如在fb函数内分配的堆空间,在main函数和fa函数中都可以使用,因为堆内存是在程序结束后会释放的。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值