Record06—栈生长属性开口方向;函数调用模型

目录

栈的生长属性是开口向上的还是开口向下的?

函数调用模型

内存的使用范围

一个主程序有n函数组成,c++编译器会建立有几个堆区?有几个栈区?

完整代码


栈的生长属性是开口向上的还是开口向下的?

栈的特点是先进后出,利用这个特点可以测出栈的生长方向是开口向上还是向下 。那如何测呢?先定义一个总方向,Y轴,向上地址值越大,向下地址值越小。那么,我可以写两个变量a,b。先让a入栈,再让b入栈。a、b入栈都会给其分配内存空间,如果给b分配的地址比给a分配的地址大, 那么就说明开口向上,反之开口向下。

那么根据程序进行测试:

void main71()
{
	int a;
	int b ;
	printf("&a:%d , &b: %d \n", &a, &b);
	system("pause");
	return ;
}

运行结果如下,a先进,b后进。发现给b分配的地址比给a分配的地址小。可以证明栈区的开口方向是向下的。

常识性的结论: 一般情况下,操作系统为用户搭建的内存四区的开口方向是向下的。应该说的是,不同的编译器,对应的开口方向是不确定的。对这个事情有个了解就行了,一般是向下的,但不可一概而论。

这样设计的缘故是为了避免栈的溢出。如果我们提前把栈的最大值给设定好,向下压栈的过程,栈的剩余空间会越来越小,防止栈的溢出。

那么,引入另一个问题,如果我在栈里引入一个变量buf:

	char buf[128];  //静态编译的时候 buf所代表的内存空间的标号 就已经定义下来了....

不管栈的生长方向是向下还是向上,变量buf的内存地址buf+1,生长方向都是向上的。这是因为这个是静态编译,言外之意就是,在你编译之前就确定好你设置的内存的起点和终点是那,有没有超过范围。而如果是在开口向下的栈中,buf的内存首地址,就是在靠下部分开始往上生长;如果是在开口向上的栈中,buf的内存首地址,依旧就是在靠下部分开始往上生长。

 

 

函数调用模型

假设一个运行程序,一个主程序main,其中,第十行有子函数fa,子函数fa中又嵌套一个子函数fb,那这三个函数之间的调用模型是怎么样的呢?

main函数正常运行,把需要的入栈的变量入栈,需要出栈的变量运行进行出栈,当到第十行发现有个内嵌的子函数fa的时候,提前把第十一行代码入栈,然后,开始执行fa,把子函数fa需要入栈的变量入栈,再在fa中遇到fb,同样,再把fb对应的函数内容入栈,当fb,执行完后,把fb在栈中的内容都出栈出完了,栈中才会执行fa之前留在栈中的内容。同理,当fa中的在栈中的部分执行完了,主函数才会开始执行自己的。之所以说,提前把第十一行代码入栈,是因为栈的先进后出结构,第十一行代码内容先压入栈,再压入fa,意思就是,fa的部分不执行完,就不去回到main中的执行流程中来。只要开始执行第十一行代码,就代表fa中的内容已经执行完毕了。

 

内存的使用范围

1.main函数中的变量可以在栈区,堆区,全局区分配内存,并且因为main函数在程序执行的环节当中,不会执行完(main执行完,就代表着程序运行完了,就不在程序执行环节当中了,换句话理解,只要main没执行完,程序就一直在运行着),所以,main里面分配的内存空间不会消失,可以供main里面的子函数(fa、fb)进行使用。

2.如果是在子函数(如,fa,fb)中生成内存,可以被main使用吗?答:如果是fb中在栈上分配的内存,那就不能被fa和main函数使用;如果fb是在malloc中分配的内存(堆),可以被main和fa函数使用的;如果fb是在全局区中分配的内存,可以被main和fa函数使用的;

一个主程序有n函数组成,c++编译器会建立有几个堆区?有几个栈区?

答:C++编译器会为每一个应用程序只建立一个内存四区,一个应用程序内的函数共同使用相同的内存四区,一个应用程序只有一个主程序函数(main函数)。内存四区相当于程序的执行空间。

 

 

完整代码

dm07_堆栈的属性测试.c

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//栈的开口向上向下,,测试 release和dubug;
//一般认为:栈开口向下 

//不管栈开口向上还是向下,buf的内存地址buf+1,永远向上的..


void main71()
{
	int a;
	int b ;

	char buf[128];  //静态联邦的时候 buf所代表的内存空间的标号 就已经定义下来了....

	printf("&a:%d , &b: %d \n", &a, &b);
	system("pause");
	return ;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值